13 #include <linux/module.h>
14 #include <linux/types.h>
15 #include <linux/kernel.h>
17 #include <linux/slab.h>
23 #include <linux/pci.h>
25 #include <linux/list.h>
27 #define MOD_NAME KBUILD_BASENAME
29 #define ADDRESS_NAME_LEN 18
31 #define ROM_PROBE_STEP_SIZE (64*1024)
33 #define BIOS_CNTL 0xDC
34 #define BIOS_LOCK_ENABLE 0x02
35 #define BIOS_WRITE_ENABLE 0x01
38 #define FWH_DEC_EN1 0xD8
39 #define FWH_F8_EN 0x8000
40 #define FWH_F0_EN 0x4000
41 #define FWH_E8_EN 0x2000
42 #define FWH_E0_EN 0x1000
43 #define FWH_D8_EN 0x0800
44 #define FWH_D0_EN 0x0400
45 #define FWH_C8_EN 0x0200
46 #define FWH_C0_EN 0x0100
47 #define FWH_LEGACY_F_EN 0x0080
48 #define FWH_LEGACY_E_EN 0x0040
50 #define FWH_70_EN 0x0008
51 #define FWH_60_EN 0x0004
52 #define FWH_50_EN 0x0002
53 #define FWH_40_EN 0x0001
59 #define FWH_8MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN | FWH_E0_EN | \
60 FWH_D8_EN | FWH_D0_EN | FWH_C8_EN | FWH_C0_EN | \
61 FWH_70_EN | FWH_60_EN | FWH_50_EN | FWH_40_EN)
63 #define FWH_7MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN | FWH_E0_EN | \
64 FWH_D8_EN | FWH_D0_EN | FWH_C8_EN | FWH_C0_EN | \
65 FWH_70_EN | FWH_60_EN | FWH_50_EN)
67 #define FWH_6MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN | FWH_E0_EN | \
68 FWH_D8_EN | FWH_D0_EN | FWH_C8_EN | FWH_C0_EN | \
69 FWH_70_EN | FWH_60_EN)
71 #define FWH_5MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN | FWH_E0_EN | \
72 FWH_D8_EN | FWH_D0_EN | FWH_C8_EN | FWH_C0_EN | \
75 #define FWH_4MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN | FWH_E0_EN | \
76 FWH_D8_EN | FWH_D0_EN | FWH_C8_EN | FWH_C0_EN)
78 #define FWH_3_5MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN | FWH_E0_EN | \
79 FWH_D8_EN | FWH_D0_EN | FWH_C8_EN)
81 #define FWH_3MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN | FWH_E0_EN | \
82 FWH_D8_EN | FWH_D0_EN)
84 #define FWH_2_5MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN | FWH_E0_EN | \
87 #define FWH_2MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN | FWH_E0_EN)
89 #define FWH_1_5MiB (FWH_F8_EN | FWH_F0_EN | FWH_E8_EN)
91 #define FWH_1MiB (FWH_F8_EN | FWH_F0_EN)
93 #define FWH_0_5MiB (FWH_F8_EN)
117 static void esb2rom_cleanup(
struct esb2rom_window *
window)
129 if (map->
rsrc.parent)
136 if (window->
rsrc.parent)
150 static char *rom_probe_types[] = {
"cfi_probe",
"jedec_probe",
NULL };
151 struct esb2rom_window *window = &esb2rom_window;
153 unsigned long map_top;
191 window->
phys = 0xff400000;
192 else if ((word &
FWH_7MiB) == FWH_7MiB)
193 window->
phys = 0xff500000;
194 else if ((word &
FWH_6MiB) == FWH_6MiB)
195 window->
phys = 0xff600000;
196 else if ((word &
FWH_5MiB) == FWH_5MiB)
197 window->
phys = 0xFF700000;
198 else if ((word &
FWH_4MiB) == FWH_4MiB)
199 window->
phys = 0xffc00000;
201 window->
phys = 0xffc80000;
202 else if ((word &
FWH_3MiB) == FWH_3MiB)
203 window->
phys = 0xffd00000;
205 window->
phys = 0xffd80000;
206 else if ((word &
FWH_2MiB) == FWH_2MiB)
207 window->
phys = 0xffe00000;
209 window->
phys = 0xffe80000;
210 else if ((word &
FWH_1MiB) == FWH_1MiB)
211 window->
phys = 0xfff00000;
213 window->
phys = 0xfff80000;
215 if (window->
phys == 0) {
221 window->
phys -= 0x400000
UL;
225 pci_read_config_byte(pdev,
BIOS_CNTL, &byte);
233 pci_write_config_byte(pdev,
BIOS_CNTL, byte | BIOS_WRITE_ENABLE);
246 "%s(): Unable to register resource %pR - kernel bug?\n",
247 __func__, &window->
rsrc);
259 map_top = window->
phys;
260 if ((window->
phys & 0x3fffff) != 0) {
262 map_top = window->
phys + 0x400000;
270 if (map_top < 0xffc00000)
271 map_top = 0xffc00000;
274 while ((map_top - 1) < 0xffffffffUL) {
285 memset(map, 0,
sizeof(*map));
286 INIT_LIST_HEAD(&map->
list);
288 map->
map.phys = map_top;
289 offset = map_top - window->
phys;
292 map->
map.size = 0xffffffff
UL - map_top + 1
UL;
301 for(map->
map.bankwidth = 32; map->
map.bankwidth;
302 map->
map.bankwidth >>= 1) {
305 if (!map_bankwidth_supported(map->
map.bankwidth))
312 probe_type = rom_probe_types;
313 for(; *probe_type; probe_type++) {
323 if (map->
mtd->size > map->
map.size) {
325 " rom(%llu) larger than window(%lu). fixing...\n",
326 (
unsigned long long)map->
mtd->size, map->
map.size);
327 map->
mtd->size = map->
map.size;
329 if (window->
rsrc.parent) {
336 map->
rsrc.start = map->
map.phys;
337 map->
rsrc.end = map->
map.phys + map->
mtd->size - 1;
341 ": cannot reserve MTD resource\n");
349 cfi = map->
map.fldrv_priv;
351 cfi->
chips[i].start += offset;
362 map_top += map->
mtd->size;
365 list_add(&map->
list, &window->
maps);
374 if (list_empty(&window->
maps)) {
375 esb2rom_cleanup(window);
383 struct esb2rom_window *window = &esb2rom_window;
384 esb2rom_cleanup(window);
408 .id_table = esb2rom_pci_tbl,
409 .probe = esb2rom_init_one,
410 .remove = esb2rom_remove_one,
414 static int __init init_esb2rom(
void)
421 for (
id = esb2rom_pci_tbl;
id->vendor;
id++) {
431 retVal = esb2rom_init_one(pdev, &esb2rom_pci_tbl[0]);
438 return pci_register_driver(&esb2rom_driver);
442 static void __exit cleanup_esb2rom(
void)
444 esb2rom_remove_one(esb2rom_window.
pdev);