aic94xx_sds.c (36692B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Aic94xx SAS/SATA driver access to shared data structures and memory 4 * maps. 5 * 6 * Copyright (C) 2005 Adaptec, Inc. All rights reserved. 7 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com> 8 */ 9 10#include <linux/pci.h> 11#include <linux/slab.h> 12#include <linux/delay.h> 13 14#include "aic94xx.h" 15#include "aic94xx_reg.h" 16#include "aic94xx_sds.h" 17 18/* ---------- OCM stuff ---------- */ 19 20struct asd_ocm_dir_ent { 21 u8 type; 22 u8 offs[3]; 23 u8 _r1; 24 u8 size[3]; 25} __attribute__ ((packed)); 26 27struct asd_ocm_dir { 28 char sig[2]; 29 u8 _r1[2]; 30 u8 major; /* 0 */ 31 u8 minor; /* 0 */ 32 u8 _r2; 33 u8 num_de; 34 struct asd_ocm_dir_ent entry[15]; 35} __attribute__ ((packed)); 36 37#define OCM_DE_OCM_DIR 0x00 38#define OCM_DE_WIN_DRVR 0x01 39#define OCM_DE_BIOS_CHIM 0x02 40#define OCM_DE_RAID_ENGN 0x03 41#define OCM_DE_BIOS_INTL 0x04 42#define OCM_DE_BIOS_CHIM_OSM 0x05 43#define OCM_DE_BIOS_CHIM_DYNAMIC 0x06 44#define OCM_DE_ADDC2C_RES0 0x07 45#define OCM_DE_ADDC2C_RES1 0x08 46#define OCM_DE_ADDC2C_RES2 0x09 47#define OCM_DE_ADDC2C_RES3 0x0A 48 49#define OCM_INIT_DIR_ENTRIES 5 50/*************************************************************************** 51* OCM directory default 52***************************************************************************/ 53static struct asd_ocm_dir OCMDirInit = 54{ 55 .sig = {0x4D, 0x4F}, /* signature */ 56 .num_de = OCM_INIT_DIR_ENTRIES, /* no. of directory entries */ 57}; 58 59/*************************************************************************** 60* OCM directory Entries default 61***************************************************************************/ 62static struct asd_ocm_dir_ent OCMDirEntriesInit[OCM_INIT_DIR_ENTRIES] = 63{ 64 { 65 .type = (OCM_DE_ADDC2C_RES0), /* Entry type */ 66 .offs = {128}, /* Offset */ 67 .size = {0, 4}, /* size */ 68 }, 69 { 70 .type = (OCM_DE_ADDC2C_RES1), /* Entry type */ 71 .offs = {128, 4}, /* Offset */ 72 .size = {0, 4}, /* size */ 73 }, 74 { 75 .type = (OCM_DE_ADDC2C_RES2), /* Entry type */ 76 .offs = {128, 8}, /* Offset */ 77 .size = {0, 4}, /* size */ 78 }, 79 { 80 .type = (OCM_DE_ADDC2C_RES3), /* Entry type */ 81 .offs = {128, 12}, /* Offset */ 82 .size = {0, 4}, /* size */ 83 }, 84 { 85 .type = (OCM_DE_WIN_DRVR), /* Entry type */ 86 .offs = {128, 16}, /* Offset */ 87 .size = {128, 235, 1}, /* size */ 88 }, 89}; 90 91struct asd_bios_chim_struct { 92 char sig[4]; 93 u8 major; /* 1 */ 94 u8 minor; /* 0 */ 95 u8 bios_major; 96 u8 bios_minor; 97 __le32 bios_build; 98 u8 flags; 99 u8 pci_slot; 100 __le16 ue_num; 101 __le16 ue_size; 102 u8 _r[14]; 103 /* The unit element array is right here. 104 */ 105} __attribute__ ((packed)); 106 107/** 108 * asd_read_ocm_seg - read an on chip memory (OCM) segment 109 * @asd_ha: pointer to the host adapter structure 110 * @buffer: where to write the read data 111 * @offs: offset into OCM where to read from 112 * @size: how many bytes to read 113 * 114 * Return the number of bytes not read. Return 0 on success. 115 */ 116static int asd_read_ocm_seg(struct asd_ha_struct *asd_ha, void *buffer, 117 u32 offs, int size) 118{ 119 u8 *p = buffer; 120 if (unlikely(asd_ha->iospace)) 121 asd_read_reg_string(asd_ha, buffer, offs+OCM_BASE_ADDR, size); 122 else { 123 for ( ; size > 0; size--, offs++, p++) 124 *p = asd_read_ocm_byte(asd_ha, offs); 125 } 126 return size; 127} 128 129static int asd_read_ocm_dir(struct asd_ha_struct *asd_ha, 130 struct asd_ocm_dir *dir, u32 offs) 131{ 132 int err = asd_read_ocm_seg(asd_ha, dir, offs, sizeof(*dir)); 133 if (err) { 134 ASD_DPRINTK("couldn't read ocm segment\n"); 135 return err; 136 } 137 138 if (dir->sig[0] != 'M' || dir->sig[1] != 'O') { 139 ASD_DPRINTK("no valid dir signature(%c%c) at start of OCM\n", 140 dir->sig[0], dir->sig[1]); 141 return -ENOENT; 142 } 143 if (dir->major != 0) { 144 asd_printk("unsupported major version of ocm dir:0x%x\n", 145 dir->major); 146 return -ENOENT; 147 } 148 dir->num_de &= 0xf; 149 return 0; 150} 151 152/** 153 * asd_write_ocm_seg - write an on chip memory (OCM) segment 154 * @asd_ha: pointer to the host adapter structure 155 * @buffer: where to read the write data 156 * @offs: offset into OCM to write to 157 * @size: how many bytes to write 158 * 159 * Return the number of bytes not written. Return 0 on success. 160 */ 161static void asd_write_ocm_seg(struct asd_ha_struct *asd_ha, void *buffer, 162 u32 offs, int size) 163{ 164 u8 *p = buffer; 165 if (unlikely(asd_ha->iospace)) 166 asd_write_reg_string(asd_ha, buffer, offs+OCM_BASE_ADDR, size); 167 else { 168 for ( ; size > 0; size--, offs++, p++) 169 asd_write_ocm_byte(asd_ha, offs, *p); 170 } 171 return; 172} 173 174#define THREE_TO_NUM(X) ((X)[0] | ((X)[1] << 8) | ((X)[2] << 16)) 175 176static int asd_find_dir_entry(struct asd_ocm_dir *dir, u8 type, 177 u32 *offs, u32 *size) 178{ 179 int i; 180 struct asd_ocm_dir_ent *ent; 181 182 for (i = 0; i < dir->num_de; i++) { 183 if (dir->entry[i].type == type) 184 break; 185 } 186 if (i >= dir->num_de) 187 return -ENOENT; 188 ent = &dir->entry[i]; 189 *offs = (u32) THREE_TO_NUM(ent->offs); 190 *size = (u32) THREE_TO_NUM(ent->size); 191 return 0; 192} 193 194#define OCM_BIOS_CHIM_DE 2 195#define BC_BIOS_PRESENT 1 196 197static int asd_get_bios_chim(struct asd_ha_struct *asd_ha, 198 struct asd_ocm_dir *dir) 199{ 200 int err; 201 struct asd_bios_chim_struct *bc_struct; 202 u32 offs, size; 203 204 err = asd_find_dir_entry(dir, OCM_BIOS_CHIM_DE, &offs, &size); 205 if (err) { 206 ASD_DPRINTK("couldn't find BIOS_CHIM dir ent\n"); 207 goto out; 208 } 209 err = -ENOMEM; 210 bc_struct = kmalloc(sizeof(*bc_struct), GFP_KERNEL); 211 if (!bc_struct) { 212 asd_printk("no memory for bios_chim struct\n"); 213 goto out; 214 } 215 err = asd_read_ocm_seg(asd_ha, (void *)bc_struct, offs, 216 sizeof(*bc_struct)); 217 if (err) { 218 ASD_DPRINTK("couldn't read ocm segment\n"); 219 goto out2; 220 } 221 if (strncmp(bc_struct->sig, "SOIB", 4) 222 && strncmp(bc_struct->sig, "IPSA", 4)) { 223 ASD_DPRINTK("BIOS_CHIM entry has no valid sig(%c%c%c%c)\n", 224 bc_struct->sig[0], bc_struct->sig[1], 225 bc_struct->sig[2], bc_struct->sig[3]); 226 err = -ENOENT; 227 goto out2; 228 } 229 if (bc_struct->major != 1) { 230 asd_printk("BIOS_CHIM unsupported major version:0x%x\n", 231 bc_struct->major); 232 err = -ENOENT; 233 goto out2; 234 } 235 if (bc_struct->flags & BC_BIOS_PRESENT) { 236 asd_ha->hw_prof.bios.present = 1; 237 asd_ha->hw_prof.bios.maj = bc_struct->bios_major; 238 asd_ha->hw_prof.bios.min = bc_struct->bios_minor; 239 asd_ha->hw_prof.bios.bld = le32_to_cpu(bc_struct->bios_build); 240 ASD_DPRINTK("BIOS present (%d,%d), %d\n", 241 asd_ha->hw_prof.bios.maj, 242 asd_ha->hw_prof.bios.min, 243 asd_ha->hw_prof.bios.bld); 244 } 245 asd_ha->hw_prof.ue.num = le16_to_cpu(bc_struct->ue_num); 246 asd_ha->hw_prof.ue.size= le16_to_cpu(bc_struct->ue_size); 247 ASD_DPRINTK("ue num:%d, ue size:%d\n", asd_ha->hw_prof.ue.num, 248 asd_ha->hw_prof.ue.size); 249 size = asd_ha->hw_prof.ue.num * asd_ha->hw_prof.ue.size; 250 if (size > 0) { 251 err = -ENOMEM; 252 asd_ha->hw_prof.ue.area = kmalloc(size, GFP_KERNEL); 253 if (!asd_ha->hw_prof.ue.area) 254 goto out2; 255 err = asd_read_ocm_seg(asd_ha, (void *)asd_ha->hw_prof.ue.area, 256 offs + sizeof(*bc_struct), size); 257 if (err) { 258 kfree(asd_ha->hw_prof.ue.area); 259 asd_ha->hw_prof.ue.area = NULL; 260 asd_ha->hw_prof.ue.num = 0; 261 asd_ha->hw_prof.ue.size = 0; 262 ASD_DPRINTK("couldn't read ue entries(%d)\n", err); 263 } 264 } 265out2: 266 kfree(bc_struct); 267out: 268 return err; 269} 270 271static void 272asd_hwi_initialize_ocm_dir (struct asd_ha_struct *asd_ha) 273{ 274 int i; 275 276 /* Zero OCM */ 277 for (i = 0; i < OCM_MAX_SIZE; i += 4) 278 asd_write_ocm_dword(asd_ha, i, 0); 279 280 /* Write Dir */ 281 asd_write_ocm_seg(asd_ha, &OCMDirInit, 0, 282 sizeof(struct asd_ocm_dir)); 283 284 /* Write Dir Entries */ 285 for (i = 0; i < OCM_INIT_DIR_ENTRIES; i++) 286 asd_write_ocm_seg(asd_ha, &OCMDirEntriesInit[i], 287 sizeof(struct asd_ocm_dir) + 288 (i * sizeof(struct asd_ocm_dir_ent)) 289 , sizeof(struct asd_ocm_dir_ent)); 290 291} 292 293static int 294asd_hwi_check_ocm_access (struct asd_ha_struct *asd_ha) 295{ 296 struct pci_dev *pcidev = asd_ha->pcidev; 297 u32 reg; 298 int err = 0; 299 u32 v; 300 301 /* check if OCM has been initialized by BIOS */ 302 reg = asd_read_reg_dword(asd_ha, EXSICNFGR); 303 304 if (!(reg & OCMINITIALIZED)) { 305 err = pci_read_config_dword(pcidev, PCIC_INTRPT_STAT, &v); 306 if (err) { 307 asd_printk("couldn't access PCIC_INTRPT_STAT of %s\n", 308 pci_name(pcidev)); 309 goto out; 310 } 311 312 printk(KERN_INFO "OCM is not initialized by BIOS," 313 "reinitialize it and ignore it, current IntrptStatus" 314 "is 0x%x\n", v); 315 316 if (v) 317 err = pci_write_config_dword(pcidev, 318 PCIC_INTRPT_STAT, v); 319 if (err) { 320 asd_printk("couldn't write PCIC_INTRPT_STAT of %s\n", 321 pci_name(pcidev)); 322 goto out; 323 } 324 325 asd_hwi_initialize_ocm_dir(asd_ha); 326 327 } 328out: 329 return err; 330} 331 332/** 333 * asd_read_ocm - read on chip memory (OCM) 334 * @asd_ha: pointer to the host adapter structure 335 */ 336int asd_read_ocm(struct asd_ha_struct *asd_ha) 337{ 338 int err; 339 struct asd_ocm_dir *dir; 340 341 if (asd_hwi_check_ocm_access(asd_ha)) 342 return -1; 343 344 dir = kmalloc(sizeof(*dir), GFP_KERNEL); 345 if (!dir) { 346 asd_printk("no memory for ocm dir\n"); 347 return -ENOMEM; 348 } 349 350 err = asd_read_ocm_dir(asd_ha, dir, 0); 351 if (err) 352 goto out; 353 354 err = asd_get_bios_chim(asd_ha, dir); 355out: 356 kfree(dir); 357 return err; 358} 359 360/* ---------- FLASH stuff ---------- */ 361 362#define FLASH_RESET 0xF0 363 364#define ASD_FLASH_SIZE 0x200000 365#define FLASH_DIR_COOKIE "*** ADAPTEC FLASH DIRECTORY *** " 366#define FLASH_NEXT_ENTRY_OFFS 0x2000 367#define FLASH_MAX_DIR_ENTRIES 32 368 369#define FLASH_DE_TYPE_MASK 0x3FFFFFFF 370#define FLASH_DE_MS 0x120 371#define FLASH_DE_CTRL_A_USER 0xE0 372 373struct asd_flash_de { 374 __le32 type; 375 __le32 offs; 376 __le32 pad_size; 377 __le32 image_size; 378 __le32 chksum; 379 u8 _r[12]; 380 u8 version[32]; 381} __attribute__ ((packed)); 382 383struct asd_flash_dir { 384 u8 cookie[32]; 385 __le32 rev; /* 2 */ 386 __le32 chksum; 387 __le32 chksum_antidote; 388 __le32 bld; 389 u8 bld_id[32]; /* build id data */ 390 u8 ver_data[32]; /* date and time of build */ 391 __le32 ae_mask; 392 __le32 v_mask; 393 __le32 oc_mask; 394 u8 _r[20]; 395 struct asd_flash_de dir_entry[FLASH_MAX_DIR_ENTRIES]; 396} __attribute__ ((packed)); 397 398struct asd_manuf_sec { 399 char sig[2]; /* 'S', 'M' */ 400 u16 offs_next; 401 u8 maj; /* 0 */ 402 u8 min; /* 0 */ 403 u16 chksum; 404 u16 size; 405 u8 _r[6]; 406 u8 sas_addr[SAS_ADDR_SIZE]; 407 u8 pcba_sn[ASD_PCBA_SN_SIZE]; 408 /* Here start the other segments */ 409 u8 linked_list[]; 410} __attribute__ ((packed)); 411 412struct asd_manuf_phy_desc { 413 u8 state; /* low 4 bits */ 414#define MS_PHY_STATE_ENABLED 0 415#define MS_PHY_STATE_REPORTED 1 416#define MS_PHY_STATE_HIDDEN 2 417 u8 phy_id; 418 u16 _r; 419 u8 phy_control_0; /* mode 5 reg 0x160 */ 420 u8 phy_control_1; /* mode 5 reg 0x161 */ 421 u8 phy_control_2; /* mode 5 reg 0x162 */ 422 u8 phy_control_3; /* mode 5 reg 0x163 */ 423} __attribute__ ((packed)); 424 425struct asd_manuf_phy_param { 426 char sig[2]; /* 'P', 'M' */ 427 u16 next; 428 u8 maj; /* 0 */ 429 u8 min; /* 2 */ 430 u8 num_phy_desc; /* 8 */ 431 u8 phy_desc_size; /* 8 */ 432 u8 _r[3]; 433 u8 usage_model_id; 434 u32 _r2; 435 struct asd_manuf_phy_desc phy_desc[ASD_MAX_PHYS]; 436} __attribute__ ((packed)); 437 438#if 0 439static const char *asd_sb_type[] = { 440 "unknown", 441 "SGPIO", 442 [2 ... 0x7F] = "unknown", 443 [0x80] = "ADPT_I2C", 444 [0x81 ... 0xFF] = "VENDOR_UNIQUExx" 445}; 446#endif 447 448struct asd_ms_sb_desc { 449 u8 type; 450 u8 node_desc_index; 451 u8 conn_desc_index; 452 u8 _recvd[]; 453} __attribute__ ((packed)); 454 455#if 0 456static const char *asd_conn_type[] = { 457 [0 ... 7] = "unknown", 458 "SFF8470", 459 "SFF8482", 460 "SFF8484", 461 [0x80] = "PCIX_DAUGHTER0", 462 [0x81] = "SAS_DAUGHTER0", 463 [0x82 ... 0xFF] = "VENDOR_UNIQUExx" 464}; 465 466static const char *asd_conn_location[] = { 467 "unknown", 468 "internal", 469 "external", 470 "board_to_board", 471}; 472#endif 473 474struct asd_ms_conn_desc { 475 u8 type; 476 u8 location; 477 u8 num_sideband_desc; 478 u8 size_sideband_desc; 479 u32 _resvd; 480 u8 name[16]; 481 struct asd_ms_sb_desc sb_desc[]; 482} __attribute__ ((packed)); 483 484struct asd_nd_phy_desc { 485 u8 vp_attch_type; 486 u8 attch_specific[]; 487} __attribute__ ((packed)); 488 489#if 0 490static const char *asd_node_type[] = { 491 "IOP", 492 "IO_CONTROLLER", 493 "EXPANDER", 494 "PORT_MULTIPLIER", 495 "PORT_MULTIPLEXER", 496 "MULTI_DROP_I2C_BUS", 497}; 498#endif 499 500struct asd_ms_node_desc { 501 u8 type; 502 u8 num_phy_desc; 503 u8 size_phy_desc; 504 u8 _resvd; 505 u8 name[16]; 506 struct asd_nd_phy_desc phy_desc[]; 507} __attribute__ ((packed)); 508 509struct asd_ms_conn_map { 510 char sig[2]; /* 'M', 'C' */ 511 __le16 next; 512 u8 maj; /* 0 */ 513 u8 min; /* 0 */ 514 __le16 cm_size; /* size of this struct */ 515 u8 num_conn; 516 u8 conn_size; 517 u8 num_nodes; 518 u8 usage_model_id; 519 u32 _resvd; 520 union { 521 DECLARE_FLEX_ARRAY(struct asd_ms_conn_desc, conn_desc); 522 DECLARE_FLEX_ARRAY(struct asd_ms_node_desc, node_desc); 523 }; 524} __attribute__ ((packed)); 525 526struct asd_ctrla_phy_entry { 527 u8 sas_addr[SAS_ADDR_SIZE]; 528 u8 sas_link_rates; /* max in hi bits, min in low bits */ 529 u8 flags; 530 u8 sata_link_rates; 531 u8 _r[5]; 532} __attribute__ ((packed)); 533 534struct asd_ctrla_phy_settings { 535 u8 id0; /* P'h'y */ 536 u8 _r; 537 u16 next; 538 u8 num_phys; /* number of PHYs in the PCI function */ 539 u8 _r2[3]; 540 struct asd_ctrla_phy_entry phy_ent[ASD_MAX_PHYS]; 541} __attribute__ ((packed)); 542 543struct asd_ll_el { 544 u8 id0; 545 u8 id1; 546 __le16 next; 547 u8 something_here[]; 548} __attribute__ ((packed)); 549 550static int asd_poll_flash(struct asd_ha_struct *asd_ha) 551{ 552 int c; 553 u8 d; 554 555 for (c = 5000; c > 0; c--) { 556 d = asd_read_reg_byte(asd_ha, asd_ha->hw_prof.flash.bar); 557 d ^= asd_read_reg_byte(asd_ha, asd_ha->hw_prof.flash.bar); 558 if (!d) 559 return 0; 560 udelay(5); 561 } 562 return -ENOENT; 563} 564 565static int asd_reset_flash(struct asd_ha_struct *asd_ha) 566{ 567 int err; 568 569 err = asd_poll_flash(asd_ha); 570 if (err) 571 return err; 572 asd_write_reg_byte(asd_ha, asd_ha->hw_prof.flash.bar, FLASH_RESET); 573 err = asd_poll_flash(asd_ha); 574 575 return err; 576} 577 578static int asd_read_flash_seg(struct asd_ha_struct *asd_ha, 579 void *buffer, u32 offs, int size) 580{ 581 asd_read_reg_string(asd_ha, buffer, asd_ha->hw_prof.flash.bar+offs, 582 size); 583 return 0; 584} 585 586/** 587 * asd_find_flash_dir - finds and reads the flash directory 588 * @asd_ha: pointer to the host adapter structure 589 * @flash_dir: pointer to flash directory structure 590 * 591 * If found, the flash directory segment will be copied to 592 * @flash_dir. Return 1 if found, 0 if not. 593 */ 594static int asd_find_flash_dir(struct asd_ha_struct *asd_ha, 595 struct asd_flash_dir *flash_dir) 596{ 597 u32 v; 598 for (v = 0; v < ASD_FLASH_SIZE; v += FLASH_NEXT_ENTRY_OFFS) { 599 asd_read_flash_seg(asd_ha, flash_dir, v, 600 sizeof(FLASH_DIR_COOKIE)-1); 601 if (memcmp(flash_dir->cookie, FLASH_DIR_COOKIE, 602 sizeof(FLASH_DIR_COOKIE)-1) == 0) { 603 asd_ha->hw_prof.flash.dir_offs = v; 604 asd_read_flash_seg(asd_ha, flash_dir, v, 605 sizeof(*flash_dir)); 606 return 1; 607 } 608 } 609 return 0; 610} 611 612static int asd_flash_getid(struct asd_ha_struct *asd_ha) 613{ 614 int err = 0; 615 u32 reg; 616 617 reg = asd_read_reg_dword(asd_ha, EXSICNFGR); 618 619 if (pci_read_config_dword(asd_ha->pcidev, PCI_CONF_FLSH_BAR, 620 &asd_ha->hw_prof.flash.bar)) { 621 asd_printk("couldn't read PCI_CONF_FLSH_BAR of %s\n", 622 pci_name(asd_ha->pcidev)); 623 return -ENOENT; 624 } 625 asd_ha->hw_prof.flash.present = 1; 626 asd_ha->hw_prof.flash.wide = reg & FLASHW ? 1 : 0; 627 err = asd_reset_flash(asd_ha); 628 if (err) { 629 ASD_DPRINTK("couldn't reset flash(%d)\n", err); 630 return err; 631 } 632 return 0; 633} 634 635static u16 asd_calc_flash_chksum(u16 *p, int size) 636{ 637 u16 chksum = 0; 638 639 while (size-- > 0) 640 chksum += *p++; 641 642 return chksum; 643} 644 645 646static int asd_find_flash_de(struct asd_flash_dir *flash_dir, u32 entry_type, 647 u32 *offs, u32 *size) 648{ 649 int i; 650 struct asd_flash_de *de; 651 652 for (i = 0; i < FLASH_MAX_DIR_ENTRIES; i++) { 653 u32 type = le32_to_cpu(flash_dir->dir_entry[i].type); 654 655 type &= FLASH_DE_TYPE_MASK; 656 if (type == entry_type) 657 break; 658 } 659 if (i >= FLASH_MAX_DIR_ENTRIES) 660 return -ENOENT; 661 de = &flash_dir->dir_entry[i]; 662 *offs = le32_to_cpu(de->offs); 663 *size = le32_to_cpu(de->pad_size); 664 return 0; 665} 666 667static int asd_validate_ms(struct asd_manuf_sec *ms) 668{ 669 if (ms->sig[0] != 'S' || ms->sig[1] != 'M') { 670 ASD_DPRINTK("manuf sec: no valid sig(%c%c)\n", 671 ms->sig[0], ms->sig[1]); 672 return -ENOENT; 673 } 674 if (ms->maj != 0) { 675 asd_printk("unsupported manuf. sector. major version:%x\n", 676 ms->maj); 677 return -ENOENT; 678 } 679 ms->offs_next = le16_to_cpu((__force __le16) ms->offs_next); 680 ms->chksum = le16_to_cpu((__force __le16) ms->chksum); 681 ms->size = le16_to_cpu((__force __le16) ms->size); 682 683 if (asd_calc_flash_chksum((u16 *)ms, ms->size/2)) { 684 asd_printk("failed manuf sector checksum\n"); 685 } 686 687 return 0; 688} 689 690static int asd_ms_get_sas_addr(struct asd_ha_struct *asd_ha, 691 struct asd_manuf_sec *ms) 692{ 693 memcpy(asd_ha->hw_prof.sas_addr, ms->sas_addr, SAS_ADDR_SIZE); 694 return 0; 695} 696 697static int asd_ms_get_pcba_sn(struct asd_ha_struct *asd_ha, 698 struct asd_manuf_sec *ms) 699{ 700 memcpy(asd_ha->hw_prof.pcba_sn, ms->pcba_sn, ASD_PCBA_SN_SIZE); 701 asd_ha->hw_prof.pcba_sn[ASD_PCBA_SN_SIZE] = '\0'; 702 return 0; 703} 704 705/** 706 * asd_find_ll_by_id - find a linked list entry by its id 707 * @start: void pointer to the first element in the linked list 708 * @id0: the first byte of the id (offs 0) 709 * @id1: the second byte of the id (offs 1) 710 * 711 * @start has to be the _base_ element start, since the 712 * linked list entries's offset is from this pointer. 713 * Some linked list entries use only the first id, in which case 714 * you can pass 0xFF for the second. 715 */ 716static void *asd_find_ll_by_id(void * const start, const u8 id0, const u8 id1) 717{ 718 struct asd_ll_el *el = start; 719 720 do { 721 switch (id1) { 722 default: 723 if (el->id1 == id1) { 724 fallthrough; 725 case 0xFF: 726 if (el->id0 == id0) 727 return el; 728 } 729 } 730 el = start + le16_to_cpu(el->next); 731 } while (el != start); 732 733 return NULL; 734} 735 736/** 737 * asd_ms_get_phy_params - get phy parameters from the manufacturing sector 738 * @asd_ha: pointer to the host adapter structure 739 * @manuf_sec: pointer to the manufacturing sector 740 * 741 * The manufacturing sector contans also the linked list of sub-segments, 742 * since when it was read, its size was taken from the flash directory, 743 * not from the structure size. 744 * 745 * HIDDEN phys do not count in the total count. REPORTED phys cannot 746 * be enabled but are reported and counted towards the total. 747 * ENABLED phys are enabled by default and count towards the total. 748 * The absolute total phy number is ASD_MAX_PHYS. hw_prof->num_phys 749 * merely specifies the number of phys the host adapter decided to 750 * report. E.g., it is possible for phys 0, 1 and 2 to be HIDDEN, 751 * phys 3, 4 and 5 to be REPORTED and phys 6 and 7 to be ENABLED. 752 * In this case ASD_MAX_PHYS is 8, hw_prof->num_phys is 5, and only 2 753 * are actually enabled (enabled by default, max number of phys 754 * enableable in this case). 755 */ 756static int asd_ms_get_phy_params(struct asd_ha_struct *asd_ha, 757 struct asd_manuf_sec *manuf_sec) 758{ 759 int i; 760 int en_phys = 0; 761 int rep_phys = 0; 762 struct asd_manuf_phy_param *phy_param; 763 struct asd_manuf_phy_param dflt_phy_param; 764 765 phy_param = asd_find_ll_by_id(manuf_sec, 'P', 'M'); 766 if (!phy_param) { 767 ASD_DPRINTK("ms: no phy parameters found\n"); 768 ASD_DPRINTK("ms: Creating default phy parameters\n"); 769 dflt_phy_param.sig[0] = 'P'; 770 dflt_phy_param.sig[1] = 'M'; 771 dflt_phy_param.maj = 0; 772 dflt_phy_param.min = 2; 773 dflt_phy_param.num_phy_desc = 8; 774 dflt_phy_param.phy_desc_size = sizeof(struct asd_manuf_phy_desc); 775 for (i =0; i < ASD_MAX_PHYS; i++) { 776 dflt_phy_param.phy_desc[i].state = 0; 777 dflt_phy_param.phy_desc[i].phy_id = i; 778 dflt_phy_param.phy_desc[i].phy_control_0 = 0xf6; 779 dflt_phy_param.phy_desc[i].phy_control_1 = 0x10; 780 dflt_phy_param.phy_desc[i].phy_control_2 = 0x43; 781 dflt_phy_param.phy_desc[i].phy_control_3 = 0xeb; 782 } 783 784 phy_param = &dflt_phy_param; 785 786 } 787 788 if (phy_param->maj != 0) { 789 asd_printk("unsupported manuf. phy param major version:0x%x\n", 790 phy_param->maj); 791 return -ENOENT; 792 } 793 794 ASD_DPRINTK("ms: num_phy_desc: %d\n", phy_param->num_phy_desc); 795 asd_ha->hw_prof.enabled_phys = 0; 796 for (i = 0; i < phy_param->num_phy_desc; i++) { 797 struct asd_manuf_phy_desc *pd = &phy_param->phy_desc[i]; 798 switch (pd->state & 0xF) { 799 case MS_PHY_STATE_HIDDEN: 800 ASD_DPRINTK("ms: phy%d: HIDDEN\n", i); 801 continue; 802 case MS_PHY_STATE_REPORTED: 803 ASD_DPRINTK("ms: phy%d: REPORTED\n", i); 804 asd_ha->hw_prof.enabled_phys &= ~(1 << i); 805 rep_phys++; 806 continue; 807 case MS_PHY_STATE_ENABLED: 808 ASD_DPRINTK("ms: phy%d: ENABLED\n", i); 809 asd_ha->hw_prof.enabled_phys |= (1 << i); 810 en_phys++; 811 break; 812 } 813 asd_ha->hw_prof.phy_desc[i].phy_control_0 = pd->phy_control_0; 814 asd_ha->hw_prof.phy_desc[i].phy_control_1 = pd->phy_control_1; 815 asd_ha->hw_prof.phy_desc[i].phy_control_2 = pd->phy_control_2; 816 asd_ha->hw_prof.phy_desc[i].phy_control_3 = pd->phy_control_3; 817 } 818 asd_ha->hw_prof.max_phys = rep_phys + en_phys; 819 asd_ha->hw_prof.num_phys = en_phys; 820 ASD_DPRINTK("ms: max_phys:0x%x, num_phys:0x%x\n", 821 asd_ha->hw_prof.max_phys, asd_ha->hw_prof.num_phys); 822 ASD_DPRINTK("ms: enabled_phys:0x%x\n", asd_ha->hw_prof.enabled_phys); 823 return 0; 824} 825 826static int asd_ms_get_connector_map(struct asd_ha_struct *asd_ha, 827 struct asd_manuf_sec *manuf_sec) 828{ 829 struct asd_ms_conn_map *cm; 830 831 cm = asd_find_ll_by_id(manuf_sec, 'M', 'C'); 832 if (!cm) { 833 ASD_DPRINTK("ms: no connector map found\n"); 834 return 0; 835 } 836 837 if (cm->maj != 0) { 838 ASD_DPRINTK("ms: unsupported: connector map major version 0x%x" 839 "\n", cm->maj); 840 return -ENOENT; 841 } 842 843 /* XXX */ 844 845 return 0; 846} 847 848 849/** 850 * asd_process_ms - find and extract information from the manufacturing sector 851 * @asd_ha: pointer to the host adapter structure 852 * @flash_dir: pointer to the flash directory 853 */ 854static int asd_process_ms(struct asd_ha_struct *asd_ha, 855 struct asd_flash_dir *flash_dir) 856{ 857 int err; 858 struct asd_manuf_sec *manuf_sec; 859 u32 offs, size; 860 861 err = asd_find_flash_de(flash_dir, FLASH_DE_MS, &offs, &size); 862 if (err) { 863 ASD_DPRINTK("Couldn't find the manuf. sector\n"); 864 goto out; 865 } 866 867 if (size == 0) 868 goto out; 869 870 err = -ENOMEM; 871 manuf_sec = kmalloc(size, GFP_KERNEL); 872 if (!manuf_sec) { 873 ASD_DPRINTK("no mem for manuf sector\n"); 874 goto out; 875 } 876 877 err = asd_read_flash_seg(asd_ha, (void *)manuf_sec, offs, size); 878 if (err) { 879 ASD_DPRINTK("couldn't read manuf sector at 0x%x, size 0x%x\n", 880 offs, size); 881 goto out2; 882 } 883 884 err = asd_validate_ms(manuf_sec); 885 if (err) { 886 ASD_DPRINTK("couldn't validate manuf sector\n"); 887 goto out2; 888 } 889 890 err = asd_ms_get_sas_addr(asd_ha, manuf_sec); 891 if (err) { 892 ASD_DPRINTK("couldn't read the SAS_ADDR\n"); 893 goto out2; 894 } 895 ASD_DPRINTK("manuf sect SAS_ADDR %llx\n", 896 SAS_ADDR(asd_ha->hw_prof.sas_addr)); 897 898 err = asd_ms_get_pcba_sn(asd_ha, manuf_sec); 899 if (err) { 900 ASD_DPRINTK("couldn't read the PCBA SN\n"); 901 goto out2; 902 } 903 ASD_DPRINTK("manuf sect PCBA SN %s\n", asd_ha->hw_prof.pcba_sn); 904 905 err = asd_ms_get_phy_params(asd_ha, manuf_sec); 906 if (err) { 907 ASD_DPRINTK("ms: couldn't get phy parameters\n"); 908 goto out2; 909 } 910 911 err = asd_ms_get_connector_map(asd_ha, manuf_sec); 912 if (err) { 913 ASD_DPRINTK("ms: couldn't get connector map\n"); 914 goto out2; 915 } 916 917out2: 918 kfree(manuf_sec); 919out: 920 return err; 921} 922 923static int asd_process_ctrla_phy_settings(struct asd_ha_struct *asd_ha, 924 struct asd_ctrla_phy_settings *ps) 925{ 926 int i; 927 for (i = 0; i < ps->num_phys; i++) { 928 struct asd_ctrla_phy_entry *pe = &ps->phy_ent[i]; 929 930 if (!PHY_ENABLED(asd_ha, i)) 931 continue; 932 if (*(u64 *)pe->sas_addr == 0) { 933 asd_ha->hw_prof.enabled_phys &= ~(1 << i); 934 continue; 935 } 936 /* This is the SAS address which should be sent in IDENTIFY. */ 937 memcpy(asd_ha->hw_prof.phy_desc[i].sas_addr, pe->sas_addr, 938 SAS_ADDR_SIZE); 939 asd_ha->hw_prof.phy_desc[i].max_sas_lrate = 940 (pe->sas_link_rates & 0xF0) >> 4; 941 asd_ha->hw_prof.phy_desc[i].min_sas_lrate = 942 (pe->sas_link_rates & 0x0F); 943 asd_ha->hw_prof.phy_desc[i].max_sata_lrate = 944 (pe->sata_link_rates & 0xF0) >> 4; 945 asd_ha->hw_prof.phy_desc[i].min_sata_lrate = 946 (pe->sata_link_rates & 0x0F); 947 asd_ha->hw_prof.phy_desc[i].flags = pe->flags; 948 ASD_DPRINTK("ctrla: phy%d: sas_addr: %llx, sas rate:0x%x-0x%x," 949 " sata rate:0x%x-0x%x, flags:0x%x\n", 950 i, 951 SAS_ADDR(asd_ha->hw_prof.phy_desc[i].sas_addr), 952 asd_ha->hw_prof.phy_desc[i].max_sas_lrate, 953 asd_ha->hw_prof.phy_desc[i].min_sas_lrate, 954 asd_ha->hw_prof.phy_desc[i].max_sata_lrate, 955 asd_ha->hw_prof.phy_desc[i].min_sata_lrate, 956 asd_ha->hw_prof.phy_desc[i].flags); 957 } 958 959 return 0; 960} 961 962/** 963 * asd_process_ctrl_a_user - process CTRL-A user settings 964 * @asd_ha: pointer to the host adapter structure 965 * @flash_dir: pointer to the flash directory 966 */ 967static int asd_process_ctrl_a_user(struct asd_ha_struct *asd_ha, 968 struct asd_flash_dir *flash_dir) 969{ 970 int err, i; 971 u32 offs, size; 972 struct asd_ll_el *el = NULL; 973 struct asd_ctrla_phy_settings *ps; 974 struct asd_ctrla_phy_settings dflt_ps; 975 976 err = asd_find_flash_de(flash_dir, FLASH_DE_CTRL_A_USER, &offs, &size); 977 if (err) { 978 ASD_DPRINTK("couldn't find CTRL-A user settings section\n"); 979 ASD_DPRINTK("Creating default CTRL-A user settings section\n"); 980 981 dflt_ps.id0 = 'h'; 982 dflt_ps.num_phys = 8; 983 for (i =0; i < ASD_MAX_PHYS; i++) { 984 memcpy(dflt_ps.phy_ent[i].sas_addr, 985 asd_ha->hw_prof.sas_addr, SAS_ADDR_SIZE); 986 dflt_ps.phy_ent[i].sas_link_rates = 0x98; 987 dflt_ps.phy_ent[i].flags = 0x0; 988 dflt_ps.phy_ent[i].sata_link_rates = 0x0; 989 } 990 991 size = sizeof(struct asd_ctrla_phy_settings); 992 ps = &dflt_ps; 993 goto out_process; 994 } 995 996 if (size == 0) 997 goto out; 998 999 err = -ENOMEM; 1000 el = kmalloc(size, GFP_KERNEL); 1001 if (!el) { 1002 ASD_DPRINTK("no mem for ctrla user settings section\n"); 1003 goto out; 1004 } 1005 1006 err = asd_read_flash_seg(asd_ha, (void *)el, offs, size); 1007 if (err) { 1008 ASD_DPRINTK("couldn't read ctrla phy settings section\n"); 1009 goto out2; 1010 } 1011 1012 err = -ENOENT; 1013 ps = asd_find_ll_by_id(el, 'h', 0xFF); 1014 if (!ps) { 1015 ASD_DPRINTK("couldn't find ctrla phy settings struct\n"); 1016 goto out2; 1017 } 1018out_process: 1019 err = asd_process_ctrla_phy_settings(asd_ha, ps); 1020 if (err) { 1021 ASD_DPRINTK("couldn't process ctrla phy settings\n"); 1022 goto out2; 1023 } 1024out2: 1025 kfree(el); 1026out: 1027 return err; 1028} 1029 1030/** 1031 * asd_read_flash - read flash memory 1032 * @asd_ha: pointer to the host adapter structure 1033 */ 1034int asd_read_flash(struct asd_ha_struct *asd_ha) 1035{ 1036 int err; 1037 struct asd_flash_dir *flash_dir; 1038 1039 err = asd_flash_getid(asd_ha); 1040 if (err) 1041 return err; 1042 1043 flash_dir = kmalloc(sizeof(*flash_dir), GFP_KERNEL); 1044 if (!flash_dir) 1045 return -ENOMEM; 1046 1047 err = -ENOENT; 1048 if (!asd_find_flash_dir(asd_ha, flash_dir)) { 1049 ASD_DPRINTK("couldn't find flash directory\n"); 1050 goto out; 1051 } 1052 1053 if (le32_to_cpu(flash_dir->rev) != 2) { 1054 asd_printk("unsupported flash dir version:0x%x\n", 1055 le32_to_cpu(flash_dir->rev)); 1056 goto out; 1057 } 1058 1059 err = asd_process_ms(asd_ha, flash_dir); 1060 if (err) { 1061 ASD_DPRINTK("couldn't process manuf sector settings\n"); 1062 goto out; 1063 } 1064 1065 err = asd_process_ctrl_a_user(asd_ha, flash_dir); 1066 if (err) { 1067 ASD_DPRINTK("couldn't process CTRL-A user settings\n"); 1068 goto out; 1069 } 1070 1071out: 1072 kfree(flash_dir); 1073 return err; 1074} 1075 1076/** 1077 * asd_verify_flash_seg - verify data with flash memory 1078 * @asd_ha: pointer to the host adapter structure 1079 * @src: pointer to the source data to be verified 1080 * @dest_offset: offset from flash memory 1081 * @bytes_to_verify: total bytes to verify 1082 */ 1083int asd_verify_flash_seg(struct asd_ha_struct *asd_ha, 1084 const void *src, u32 dest_offset, u32 bytes_to_verify) 1085{ 1086 const u8 *src_buf; 1087 u8 flash_char; 1088 int err; 1089 u32 nv_offset, reg, i; 1090 1091 reg = asd_ha->hw_prof.flash.bar; 1092 src_buf = NULL; 1093 1094 err = FLASH_OK; 1095 nv_offset = dest_offset; 1096 src_buf = (const u8 *)src; 1097 for (i = 0; i < bytes_to_verify; i++) { 1098 flash_char = asd_read_reg_byte(asd_ha, reg + nv_offset + i); 1099 if (flash_char != src_buf[i]) { 1100 err = FAIL_VERIFY; 1101 break; 1102 } 1103 } 1104 return err; 1105} 1106 1107/** 1108 * asd_write_flash_seg - write data into flash memory 1109 * @asd_ha: pointer to the host adapter structure 1110 * @src: pointer to the source data to be written 1111 * @dest_offset: offset from flash memory 1112 * @bytes_to_write: total bytes to write 1113 */ 1114int asd_write_flash_seg(struct asd_ha_struct *asd_ha, 1115 const void *src, u32 dest_offset, u32 bytes_to_write) 1116{ 1117 const u8 *src_buf; 1118 u32 nv_offset, reg, i; 1119 int err; 1120 1121 reg = asd_ha->hw_prof.flash.bar; 1122 src_buf = NULL; 1123 1124 err = asd_check_flash_type(asd_ha); 1125 if (err) { 1126 ASD_DPRINTK("couldn't find the type of flash. err=%d\n", err); 1127 return err; 1128 } 1129 1130 nv_offset = dest_offset; 1131 err = asd_erase_nv_sector(asd_ha, nv_offset, bytes_to_write); 1132 if (err) { 1133 ASD_DPRINTK("Erase failed at offset:0x%x\n", 1134 nv_offset); 1135 return err; 1136 } 1137 1138 err = asd_reset_flash(asd_ha); 1139 if (err) { 1140 ASD_DPRINTK("couldn't reset flash. err=%d\n", err); 1141 return err; 1142 } 1143 1144 src_buf = (const u8 *)src; 1145 for (i = 0; i < bytes_to_write; i++) { 1146 /* Setup program command sequence */ 1147 switch (asd_ha->hw_prof.flash.method) { 1148 case FLASH_METHOD_A: 1149 { 1150 asd_write_reg_byte(asd_ha, 1151 (reg + 0xAAA), 0xAA); 1152 asd_write_reg_byte(asd_ha, 1153 (reg + 0x555), 0x55); 1154 asd_write_reg_byte(asd_ha, 1155 (reg + 0xAAA), 0xA0); 1156 asd_write_reg_byte(asd_ha, 1157 (reg + nv_offset + i), 1158 (*(src_buf + i))); 1159 break; 1160 } 1161 case FLASH_METHOD_B: 1162 { 1163 asd_write_reg_byte(asd_ha, 1164 (reg + 0x555), 0xAA); 1165 asd_write_reg_byte(asd_ha, 1166 (reg + 0x2AA), 0x55); 1167 asd_write_reg_byte(asd_ha, 1168 (reg + 0x555), 0xA0); 1169 asd_write_reg_byte(asd_ha, 1170 (reg + nv_offset + i), 1171 (*(src_buf + i))); 1172 break; 1173 } 1174 default: 1175 break; 1176 } 1177 if (asd_chk_write_status(asd_ha, 1178 (nv_offset + i), 0) != 0) { 1179 ASD_DPRINTK("aicx: Write failed at offset:0x%x\n", 1180 reg + nv_offset + i); 1181 return FAIL_WRITE_FLASH; 1182 } 1183 } 1184 1185 err = asd_reset_flash(asd_ha); 1186 if (err) { 1187 ASD_DPRINTK("couldn't reset flash. err=%d\n", err); 1188 return err; 1189 } 1190 return 0; 1191} 1192 1193int asd_chk_write_status(struct asd_ha_struct *asd_ha, 1194 u32 sector_addr, u8 erase_flag) 1195{ 1196 u32 reg; 1197 u32 loop_cnt; 1198 u8 nv_data1, nv_data2; 1199 u8 toggle_bit1; 1200 1201 /* 1202 * Read from DQ2 requires sector address 1203 * while it's dont care for DQ6 1204 */ 1205 reg = asd_ha->hw_prof.flash.bar; 1206 1207 for (loop_cnt = 0; loop_cnt < 50000; loop_cnt++) { 1208 nv_data1 = asd_read_reg_byte(asd_ha, reg); 1209 nv_data2 = asd_read_reg_byte(asd_ha, reg); 1210 1211 toggle_bit1 = ((nv_data1 & FLASH_STATUS_BIT_MASK_DQ6) 1212 ^ (nv_data2 & FLASH_STATUS_BIT_MASK_DQ6)); 1213 1214 if (toggle_bit1 == 0) { 1215 return 0; 1216 } else { 1217 if (nv_data2 & FLASH_STATUS_BIT_MASK_DQ5) { 1218 nv_data1 = asd_read_reg_byte(asd_ha, 1219 reg); 1220 nv_data2 = asd_read_reg_byte(asd_ha, 1221 reg); 1222 toggle_bit1 = 1223 ((nv_data1 & FLASH_STATUS_BIT_MASK_DQ6) 1224 ^ (nv_data2 & FLASH_STATUS_BIT_MASK_DQ6)); 1225 1226 if (toggle_bit1 == 0) 1227 return 0; 1228 } 1229 } 1230 1231 /* 1232 * ERASE is a sector-by-sector operation and requires 1233 * more time to finish while WRITE is byte-byte-byte 1234 * operation and takes lesser time to finish. 1235 * 1236 * For some strange reason a reduced ERASE delay gives different 1237 * behaviour across different spirit boards. Hence we set 1238 * a optimum balance of 50mus for ERASE which works well 1239 * across all boards. 1240 */ 1241 if (erase_flag) { 1242 udelay(FLASH_STATUS_ERASE_DELAY_COUNT); 1243 } else { 1244 udelay(FLASH_STATUS_WRITE_DELAY_COUNT); 1245 } 1246 } 1247 return -1; 1248} 1249 1250/** 1251 * asd_erase_nv_sector - Erase the flash memory sectors. 1252 * @asd_ha: pointer to the host adapter structure 1253 * @flash_addr: pointer to offset from flash memory 1254 * @size: total bytes to erase. 1255 */ 1256int asd_erase_nv_sector(struct asd_ha_struct *asd_ha, u32 flash_addr, u32 size) 1257{ 1258 u32 reg; 1259 u32 sector_addr; 1260 1261 reg = asd_ha->hw_prof.flash.bar; 1262 1263 /* sector staring address */ 1264 sector_addr = flash_addr & FLASH_SECTOR_SIZE_MASK; 1265 1266 /* 1267 * Erasing an flash sector needs to be done in six consecutive 1268 * write cyles. 1269 */ 1270 while (sector_addr < flash_addr+size) { 1271 switch (asd_ha->hw_prof.flash.method) { 1272 case FLASH_METHOD_A: 1273 asd_write_reg_byte(asd_ha, (reg + 0xAAA), 0xAA); 1274 asd_write_reg_byte(asd_ha, (reg + 0x555), 0x55); 1275 asd_write_reg_byte(asd_ha, (reg + 0xAAA), 0x80); 1276 asd_write_reg_byte(asd_ha, (reg + 0xAAA), 0xAA); 1277 asd_write_reg_byte(asd_ha, (reg + 0x555), 0x55); 1278 asd_write_reg_byte(asd_ha, (reg + sector_addr), 0x30); 1279 break; 1280 case FLASH_METHOD_B: 1281 asd_write_reg_byte(asd_ha, (reg + 0x555), 0xAA); 1282 asd_write_reg_byte(asd_ha, (reg + 0x2AA), 0x55); 1283 asd_write_reg_byte(asd_ha, (reg + 0x555), 0x80); 1284 asd_write_reg_byte(asd_ha, (reg + 0x555), 0xAA); 1285 asd_write_reg_byte(asd_ha, (reg + 0x2AA), 0x55); 1286 asd_write_reg_byte(asd_ha, (reg + sector_addr), 0x30); 1287 break; 1288 default: 1289 break; 1290 } 1291 1292 if (asd_chk_write_status(asd_ha, sector_addr, 1) != 0) 1293 return FAIL_ERASE_FLASH; 1294 1295 sector_addr += FLASH_SECTOR_SIZE; 1296 } 1297 1298 return 0; 1299} 1300 1301int asd_check_flash_type(struct asd_ha_struct *asd_ha) 1302{ 1303 u8 manuf_id; 1304 u8 dev_id; 1305 u8 sec_prot; 1306 u32 inc; 1307 u32 reg; 1308 int err; 1309 1310 /* get Flash memory base address */ 1311 reg = asd_ha->hw_prof.flash.bar; 1312 1313 /* Determine flash info */ 1314 err = asd_reset_flash(asd_ha); 1315 if (err) { 1316 ASD_DPRINTK("couldn't reset flash. err=%d\n", err); 1317 return err; 1318 } 1319 1320 asd_ha->hw_prof.flash.method = FLASH_METHOD_UNKNOWN; 1321 asd_ha->hw_prof.flash.manuf = FLASH_MANUF_ID_UNKNOWN; 1322 asd_ha->hw_prof.flash.dev_id = FLASH_DEV_ID_UNKNOWN; 1323 1324 /* Get flash info. This would most likely be AMD Am29LV family flash. 1325 * First try the sequence for word mode. It is the same as for 1326 * 008B (byte mode only), 160B (word mode) and 800D (word mode). 1327 */ 1328 inc = asd_ha->hw_prof.flash.wide ? 2 : 1; 1329 asd_write_reg_byte(asd_ha, reg + 0xAAA, 0xAA); 1330 asd_write_reg_byte(asd_ha, reg + 0x555, 0x55); 1331 asd_write_reg_byte(asd_ha, reg + 0xAAA, 0x90); 1332 manuf_id = asd_read_reg_byte(asd_ha, reg); 1333 dev_id = asd_read_reg_byte(asd_ha, reg + inc); 1334 sec_prot = asd_read_reg_byte(asd_ha, reg + inc + inc); 1335 /* Get out of autoselect mode. */ 1336 err = asd_reset_flash(asd_ha); 1337 if (err) { 1338 ASD_DPRINTK("couldn't reset flash. err=%d\n", err); 1339 return err; 1340 } 1341 ASD_DPRINTK("Flash MethodA manuf_id(0x%x) dev_id(0x%x) " 1342 "sec_prot(0x%x)\n", manuf_id, dev_id, sec_prot); 1343 err = asd_reset_flash(asd_ha); 1344 if (err != 0) 1345 return err; 1346 1347 switch (manuf_id) { 1348 case FLASH_MANUF_ID_AMD: 1349 switch (sec_prot) { 1350 case FLASH_DEV_ID_AM29LV800DT: 1351 case FLASH_DEV_ID_AM29LV640MT: 1352 case FLASH_DEV_ID_AM29F800B: 1353 asd_ha->hw_prof.flash.method = FLASH_METHOD_A; 1354 break; 1355 default: 1356 break; 1357 } 1358 break; 1359 case FLASH_MANUF_ID_ST: 1360 switch (sec_prot) { 1361 case FLASH_DEV_ID_STM29W800DT: 1362 case FLASH_DEV_ID_STM29LV640: 1363 asd_ha->hw_prof.flash.method = FLASH_METHOD_A; 1364 break; 1365 default: 1366 break; 1367 } 1368 break; 1369 case FLASH_MANUF_ID_FUJITSU: 1370 switch (sec_prot) { 1371 case FLASH_DEV_ID_MBM29LV800TE: 1372 case FLASH_DEV_ID_MBM29DL800TA: 1373 asd_ha->hw_prof.flash.method = FLASH_METHOD_A; 1374 break; 1375 } 1376 break; 1377 case FLASH_MANUF_ID_MACRONIX: 1378 switch (sec_prot) { 1379 case FLASH_DEV_ID_MX29LV800BT: 1380 asd_ha->hw_prof.flash.method = FLASH_METHOD_A; 1381 break; 1382 } 1383 break; 1384 } 1385 1386 if (asd_ha->hw_prof.flash.method == FLASH_METHOD_UNKNOWN) { 1387 err = asd_reset_flash(asd_ha); 1388 if (err) { 1389 ASD_DPRINTK("couldn't reset flash. err=%d\n", err); 1390 return err; 1391 } 1392 1393 /* Issue Unlock sequence for AM29LV008BT */ 1394 asd_write_reg_byte(asd_ha, (reg + 0x555), 0xAA); 1395 asd_write_reg_byte(asd_ha, (reg + 0x2AA), 0x55); 1396 asd_write_reg_byte(asd_ha, (reg + 0x555), 0x90); 1397 manuf_id = asd_read_reg_byte(asd_ha, reg); 1398 dev_id = asd_read_reg_byte(asd_ha, reg + inc); 1399 sec_prot = asd_read_reg_byte(asd_ha, reg + inc + inc); 1400 1401 ASD_DPRINTK("Flash MethodB manuf_id(0x%x) dev_id(0x%x) sec_prot" 1402 "(0x%x)\n", manuf_id, dev_id, sec_prot); 1403 1404 err = asd_reset_flash(asd_ha); 1405 if (err != 0) { 1406 ASD_DPRINTK("couldn't reset flash. err=%d\n", err); 1407 return err; 1408 } 1409 1410 switch (manuf_id) { 1411 case FLASH_MANUF_ID_AMD: 1412 switch (dev_id) { 1413 case FLASH_DEV_ID_AM29LV008BT: 1414 asd_ha->hw_prof.flash.method = FLASH_METHOD_B; 1415 break; 1416 default: 1417 break; 1418 } 1419 break; 1420 case FLASH_MANUF_ID_ST: 1421 switch (dev_id) { 1422 case FLASH_DEV_ID_STM29008: 1423 asd_ha->hw_prof.flash.method = FLASH_METHOD_B; 1424 break; 1425 default: 1426 break; 1427 } 1428 break; 1429 case FLASH_MANUF_ID_FUJITSU: 1430 switch (dev_id) { 1431 case FLASH_DEV_ID_MBM29LV008TA: 1432 asd_ha->hw_prof.flash.method = FLASH_METHOD_B; 1433 break; 1434 } 1435 break; 1436 case FLASH_MANUF_ID_INTEL: 1437 switch (dev_id) { 1438 case FLASH_DEV_ID_I28LV00TAT: 1439 asd_ha->hw_prof.flash.method = FLASH_METHOD_B; 1440 break; 1441 } 1442 break; 1443 case FLASH_MANUF_ID_MACRONIX: 1444 switch (dev_id) { 1445 case FLASH_DEV_ID_I28LV00TAT: 1446 asd_ha->hw_prof.flash.method = FLASH_METHOD_B; 1447 break; 1448 } 1449 break; 1450 default: 1451 return FAIL_FIND_FLASH_ID; 1452 } 1453 } 1454 1455 if (asd_ha->hw_prof.flash.method == FLASH_METHOD_UNKNOWN) 1456 return FAIL_FIND_FLASH_ID; 1457 1458 asd_ha->hw_prof.flash.manuf = manuf_id; 1459 asd_ha->hw_prof.flash.dev_id = dev_id; 1460 asd_ha->hw_prof.flash.sec_prot = sec_prot; 1461 return 0; 1462}