42 #include <linux/module.h>
47 #define PFX "hermes_dld: "
50 #define PDI_END 0x00000000
51 #define BLOCK_END 0xFFFFFFFF
110 pdr_id(
const struct pdr *
pdr)
116 pdr_addr(
const struct pdr *
pdr)
122 pdr_len(
const struct pdr *
pdr)
130 pdi_id(
const struct pdi *
pdi)
137 pdi_len(
const struct pdi *
pdi)
148 static const struct pdr *
149 hermes_find_pdr(
const struct pdr *first_pdr,
u32 record_id,
const void *
end)
151 const struct pdr *
pdr = first_pdr;
153 end -=
sizeof(
struct pdr);
155 while (((
void *) pdr <= end) &&
162 if (pdr_len(pdr) < 2)
166 if (pdr_id(pdr) == record_id)
169 pdr = (
struct pdr *) pdr->
next;
175 static const struct pdi *
176 hermes_find_pdi(
const struct pdi *first_pdi,
u32 record_id,
const void *end)
178 const struct pdi *
pdi = first_pdi;
180 end -=
sizeof(
struct pdi);
182 while (((
void *) pdi <= end) &&
186 if (pdi_id(pdi) == record_id)
189 pdi = (
struct pdi *) &pdi->
data[pdi_len(pdi)];
196 hermes_plug_pdi(
struct hermes *
hw,
const struct pdr *first_pdr,
197 const struct pdi *pdi,
const void *pdr_end)
199 const struct pdr *pdr;
202 pdr = hermes_find_pdr(first_pdr, pdi_id(pdi), pdr_end);
209 if (pdi_len(pdi) != pdr_len(pdr))
213 hw->
ops->program(hw, pdi->
data, pdr_addr(pdr), pdi_len(pdi));
224 const char *first_pdr,
230 const struct pdi *pdi;
231 const struct pdr *pdr;
233 pdr = (
const struct pdr *) first_pdr;
234 pda_end -=
sizeof(
struct pdi);
237 pdi = (
const struct pdi *) (pda + 2);
238 while (((
void *) pdi <= pda_end) &&
240 ret = hermes_plug_pdi(hw, pdr, pdi, pdr_end);
245 pdi = (
const struct pdi *) &pdi->
data[pdi_len(pdi)];
264 while (((
void *) blk <= end) &&
266 len = dblock_len(blk);
267 total_len +=
sizeof(*blk) +
len;
284 blk = (
const struct dblock *) first_block;
286 if ((
void *) blk > (end -
sizeof(*blk)))
289 blkaddr = dblock_addr(blk);
290 blklen = dblock_len(blk);
293 (((
void *) blk + blklen) <= end)) {
295 "to address 0x%08x\n", blklen, blkaddr);
297 err = hw->
ops->program(hw, blk->
data, blkaddr, blklen);
301 blk = (
const struct dblock *) &blk->
data[blklen];
303 if ((
void *) blk > (end -
sizeof(*blk)))
306 blkaddr = dblock_addr(blk);
307 blklen = dblock_len(blk);
315 #define DEFINE_DEFAULT_PDR(pid, length, data) \
316 static const struct { \
320 } __packed default_pdr_data_##pid = { \
321 cpu_to_le16((sizeof(default_pdr_data_##pid)/ \
322 sizeof(__le16)) - 1), \
327 #define DEFAULT_PDR(pid) default_pdr_data_##pid
343 "\x00\x00\x00\x00\x00\x00\x00\x00"
344 "\x00\x00\x00\x00\x00\x00\x00\x00"
345 "\x00\x00\x00\x00\x00\x00\x00\x00"
350 "\x3F\x01\x3F\01\x3F\x01\x3F\x01"
351 "\x3F\x01\x3F\01\x3F\x01\x3F\x01"
352 "\x3F\x01\x3F\01\x3F\x01\x3F\x01"
353 "\x3F\x01\x3F\01\x3F\x01\x3F\x01"
354 "\x3F\x01\x3E\01\x3E\x01\x3D\x01"
355 "\x3D\x01\x3C\01\x3C\x01\x3B\x01"
356 "\x3B\x01\x3A\01\x3A\x01\x39\x01"
357 "\x39\x01\x38\01\x38\x01\x37\x01"
358 "\x37\x01\x36\01\x36\x01\x35\x01"
359 "\x35\x01\x34\01\x34\x01\x33\x01"
360 "\x33\x01\x32\x01\x32\x01\x31\x01"
361 "\x31\x01\x30\x01\x30\x01\x7B\x01"
362 "\x7B\x01\x7A\x01\x7A\x01\x79\x01"
363 "\x79\x01\x78\x01\x78\x01\x77\x01"
364 "\x77\x01\x76\x01\x76\x01\x75\x01"
365 "\x75\x01\x74\x01\x74\x01\x73\x01"
366 "\x73\x01\x72\x01\x72\x01\x71\x01"
367 "\x71\x01\x70\x01\x70\x01\x68\x01"
368 "\x68\x01\x67\x01\x67\x01\x66\x01"
369 "\x66\x01\x65\x01\x65\x01\x57\x01"
370 "\x57\x01\x56\x01\x56\x01\x55\x01"
371 "\x55\x01\x54\x01\x54\x01\x53\x01"
372 "\x53\x01\x52\x01\x52\x01\x51\x01"
373 "\x51\x01\x50\x01\x50\x01\x48\x01"
374 "\x48\x01\x47\x01\x47\x01\x46\x01"
375 "\x46\x01\x45\x01\x45\x01\x44\x01"
376 "\x44\x01\x43\x01\x43\x01\x42\x01"
377 "\x42\x01\x41\x01\x41\x01\x40\x01"
378 "\x40\x01\x40\x01\x40\x01\x40\x01"
379 "\x40\x01\x40\x01\x40\x01\x40\x01"
380 "\x40\x01\x40\x01\x40\x01\x40\x01"
381 "\x40\x01\x40\x01\x40\x01\x40\x01");
391 const char *first_pdr,
396 const struct pdr *pdr = (
const struct pdr *) first_pdr;
397 const struct pdi *first_pdi = (
const struct pdi *) &pda[2];
398 const struct pdi *pdi;
399 const struct pdi *default_pdi =
NULL;
400 const struct pdi *outdoor_pdi;
403 pdr_end -=
sizeof(
struct pdr);
405 while (((
void *) pdr <= pdr_end) &&
413 if (pdr_len(pdr) < 2)
415 record_id = pdr_id(pdr);
417 pdi = hermes_find_pdi(first_pdi, record_id, pda_end);
425 outdoor_pdi = hermes_find_pdi(first_pdi, record_id + 1,
431 "Using outdoor record 0x%04x at %p\n",
457 if (!pdi && default_pdi) {
460 pr_debug(
PFX "Using default record 0x%04x at %p\n",
466 if ((pdi_len(pdi) == pdr_len(pdr)) &&
467 ((
void *) pdi->
data + pdi_len(pdi) < pda_end)) {
469 hw->
ops->program(hw, pdi->
data, pdr_addr(pdr),