1 /* 2 * Aic94xx SAS/SATA driver access to shared data structures and memory 3 * maps. 4 * 5 * Copyright (C) 2005 Adaptec, Inc. All rights reserved. 6 * Copyright (C) 2005 Luben Tuikov <luben_tuikov@adaptec.com> 7 * 8 * This file is licensed under GPLv2. 9 * 10 * This file is part of the aic94xx driver. 11 * 12 * The aic94xx driver is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License as 14 * published by the Free Software Foundation; version 2 of the 15 * License. 16 * 17 * The aic94xx driver is distributed in the hope that it will be useful, 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 * General Public License for more details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with the aic94xx driver; if not, write to the Free Software 24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 25 * 26 */ 27 28 #include <linux/pci.h> 29 #include <linux/delay.h> 30 31 #include "aic94xx.h" 32 #include "aic94xx_reg.h" 33 34 /* ---------- OCM stuff ---------- */ 35 36 struct asd_ocm_dir_ent { 37 u8 type; 38 u8 offs[3]; 39 u8 _r1; 40 u8 size[3]; 41 } __attribute__ ((packed)); 42 43 struct asd_ocm_dir { 44 char sig[2]; 45 u8 _r1[2]; 46 u8 major; /* 0 */ 47 u8 minor; /* 0 */ 48 u8 _r2; 49 u8 num_de; 50 struct asd_ocm_dir_ent entry[15]; 51 } __attribute__ ((packed)); 52 53 #define OCM_DE_OCM_DIR 0x00 54 #define OCM_DE_WIN_DRVR 0x01 55 #define OCM_DE_BIOS_CHIM 0x02 56 #define OCM_DE_RAID_ENGN 0x03 57 #define OCM_DE_BIOS_INTL 0x04 58 #define OCM_DE_BIOS_CHIM_OSM 0x05 59 #define OCM_DE_BIOS_CHIM_DYNAMIC 0x06 60 #define OCM_DE_ADDC2C_RES0 0x07 61 #define OCM_DE_ADDC2C_RES1 0x08 62 #define OCM_DE_ADDC2C_RES2 0x09 63 #define OCM_DE_ADDC2C_RES3 0x0A 64 65 #define OCM_INIT_DIR_ENTRIES 5 66 /*************************************************************************** 67 * OCM directory default 68 ***************************************************************************/ 69 static struct asd_ocm_dir OCMDirInit = 70 { 71 .sig = {0x4D, 0x4F}, /* signature */ 72 .num_de = OCM_INIT_DIR_ENTRIES, /* no. of directory entries */ 73 }; 74 75 /*************************************************************************** 76 * OCM directory Entries default 77 ***************************************************************************/ 78 static struct asd_ocm_dir_ent OCMDirEntriesInit[OCM_INIT_DIR_ENTRIES] = 79 { 80 { 81 .type = (OCM_DE_ADDC2C_RES0), /* Entry type */ 82 .offs = {128}, /* Offset */ 83 .size = {0, 4}, /* size */ 84 }, 85 { 86 .type = (OCM_DE_ADDC2C_RES1), /* Entry type */ 87 .offs = {128, 4}, /* Offset */ 88 .size = {0, 4}, /* size */ 89 }, 90 { 91 .type = (OCM_DE_ADDC2C_RES2), /* Entry type */ 92 .offs = {128, 8}, /* Offset */ 93 .size = {0, 4}, /* size */ 94 }, 95 { 96 .type = (OCM_DE_ADDC2C_RES3), /* Entry type */ 97 .offs = {128, 12}, /* Offset */ 98 .size = {0, 4}, /* size */ 99 }, 100 { 101 .type = (OCM_DE_WIN_DRVR), /* Entry type */ 102 .offs = {128, 16}, /* Offset */ 103 .size = {128, 235, 1}, /* size */ 104 }, 105 }; 106 107 struct asd_bios_chim_struct { 108 char sig[4]; 109 u8 major; /* 1 */ 110 u8 minor; /* 0 */ 111 u8 bios_major; 112 u8 bios_minor; 113 __le32 bios_build; 114 u8 flags; 115 u8 pci_slot; 116 __le16 ue_num; 117 __le16 ue_size; 118 u8 _r[14]; 119 /* The unit element array is right here. 120 */ 121 } __attribute__ ((packed)); 122 123 /** 124 * asd_read_ocm_seg - read an on chip memory (OCM) segment 125 * @asd_ha: pointer to the host adapter structure 126 * @buffer: where to write the read data 127 * @offs: offset into OCM where to read from 128 * @size: how many bytes to read 129 * 130 * Return the number of bytes not read. Return 0 on success. 131 */ 132 static int asd_read_ocm_seg(struct asd_ha_struct *asd_ha, void *buffer, 133 u32 offs, int size) 134 { 135 u8 *p = buffer; 136 if (unlikely(asd_ha->iospace)) 137 asd_read_reg_string(asd_ha, buffer, offs+OCM_BASE_ADDR, size); 138 else { 139 for ( ; size > 0; size--, offs++, p++) 140 *p = asd_read_ocm_byte(asd_ha, offs); 141 } 142 return size; 143 } 144 145 static int asd_read_ocm_dir(struct asd_ha_struct *asd_ha, 146 struct asd_ocm_dir *dir, u32 offs) 147 { 148 int err = asd_read_ocm_seg(asd_ha, dir, offs, sizeof(*dir)); 149 if (err) { 150 ASD_DPRINTK("couldn't read ocm segment\n"); 151 return err; 152 } 153 154 if (dir->sig[0] != 'M' || dir->sig[1] != 'O') { 155 ASD_DPRINTK("no valid dir signature(%c%c) at start of OCM\n", 156 dir->sig[0], dir->sig[1]); 157 return -ENOENT; 158 } 159 if (dir->major != 0) { 160 asd_printk("unsupported major version of ocm dir:0x%x\n", 161 dir->major); 162 return -ENOENT; 163 } 164 dir->num_de &= 0xf; 165 return 0; 166 } 167 168 /** 169 * asd_write_ocm_seg - write an on chip memory (OCM) segment 170 * @asd_ha: pointer to the host adapter structure 171 * @buffer: where to read the write data 172 * @offs: offset into OCM to write to 173 * @size: how many bytes to write 174 * 175 * Return the number of bytes not written. Return 0 on success. 176 */ 177 static void asd_write_ocm_seg(struct asd_ha_struct *asd_ha, void *buffer, 178 u32 offs, int size) 179 { 180 u8 *p = buffer; 181 if (unlikely(asd_ha->iospace)) 182 asd_write_reg_string(asd_ha, buffer, offs+OCM_BASE_ADDR, size); 183 else { 184 for ( ; size > 0; size--, offs++, p++) 185 asd_write_ocm_byte(asd_ha, offs, *p); 186 } 187 return; 188 } 189 190 #define THREE_TO_NUM(X) ((X)[0] | ((X)[1] << 8) | ((X)[2] << 16)) 191 192 static int asd_find_dir_entry(struct asd_ocm_dir *dir, u8 type, 193 u32 *offs, u32 *size) 194 { 195 int i; 196 struct asd_ocm_dir_ent *ent; 197 198 for (i = 0; i < dir->num_de; i++) { 199 if (dir->entry[i].type == type) 200 break; 201 } 202 if (i >= dir->num_de) 203 return -ENOENT; 204 ent = &dir->entry[i]; 205 *offs = (u32) THREE_TO_NUM(ent->offs); 206 *size = (u32) THREE_TO_NUM(ent->size); 207 return 0; 208 } 209 210 #define OCM_BIOS_CHIM_DE 2 211 #define BC_BIOS_PRESENT 1 212 213 static int asd_get_bios_chim(struct asd_ha_struct *asd_ha, 214 struct asd_ocm_dir *dir) 215 { 216 int err; 217 struct asd_bios_chim_struct *bc_struct; 218 u32 offs, size; 219 220 err = asd_find_dir_entry(dir, OCM_BIOS_CHIM_DE, &offs, &size); 221 if (err) { 222 ASD_DPRINTK("couldn't find BIOS_CHIM dir ent\n"); 223 goto out; 224 } 225 err = -ENOMEM; 226 bc_struct = kmalloc(sizeof(*bc_struct), GFP_KERNEL); 227 if (!bc_struct) { 228 asd_printk("no memory for bios_chim struct\n"); 229 goto out; 230 } 231 err = asd_read_ocm_seg(asd_ha, (void *)bc_struct, offs, 232 sizeof(*bc_struct)); 233 if (err) { 234 ASD_DPRINTK("couldn't read ocm segment\n"); 235 goto out2; 236 } 237 if (strncmp(bc_struct->sig, "SOIB", 4) 238 && strncmp(bc_struct->sig, "IPSA", 4)) { 239 ASD_DPRINTK("BIOS_CHIM entry has no valid sig(%c%c%c%c)\n", 240 bc_struct->sig[0], bc_struct->sig[1], 241 bc_struct->sig[2], bc_struct->sig[3]); 242 err = -ENOENT; 243 goto out2; 244 } 245 if (bc_struct->major != 1) { 246 asd_printk("BIOS_CHIM unsupported major version:0x%x\n", 247 bc_struct->major); 248 err = -ENOENT; 249 goto out2; 250 } 251 if (bc_struct->flags & BC_BIOS_PRESENT) { 252 asd_ha->hw_prof.bios.present = 1; 253 asd_ha->hw_prof.bios.maj = bc_struct->bios_major; 254 asd_ha->hw_prof.bios.min = bc_struct->bios_minor; 255 asd_ha->hw_prof.bios.bld = le32_to_cpu(bc_struct->bios_build); 256 ASD_DPRINTK("BIOS present (%d,%d), %d\n", 257 asd_ha->hw_prof.bios.maj, 258 asd_ha->hw_prof.bios.min, 259 asd_ha->hw_prof.bios.bld); 260 } 261 asd_ha->hw_prof.ue.num = le16_to_cpu(bc_struct->ue_num); 262 asd_ha->hw_prof.ue.size= le16_to_cpu(bc_struct->ue_size); 263 ASD_DPRINTK("ue num:%d, ue size:%d\n", asd_ha->hw_prof.ue.num, 264 asd_ha->hw_prof.ue.size); 265 size = asd_ha->hw_prof.ue.num * asd_ha->hw_prof.ue.size; 266 if (size > 0) { 267 err = -ENOMEM; 268 asd_ha->hw_prof.ue.area = kmalloc(size, GFP_KERNEL); 269 if (!asd_ha->hw_prof.ue.area) 270 goto out2; 271 err = asd_read_ocm_seg(asd_ha, (void *)asd_ha->hw_prof.ue.area, 272 offs + sizeof(*bc_struct), size); 273 if (err) { 274 kfree(asd_ha->hw_prof.ue.area); 275 asd_ha->hw_prof.ue.area = NULL; 276 asd_ha->hw_prof.ue.num = 0; 277 asd_ha->hw_prof.ue.size = 0; 278 ASD_DPRINTK("couldn't read ue entries(%d)\n", err); 279 } 280 } 281 out2: 282 kfree(bc_struct); 283 out: 284 return err; 285 } 286 287 static void 288 asd_hwi_initialize_ocm_dir (struct asd_ha_struct *asd_ha) 289 { 290 int i; 291 292 /* Zero OCM */ 293 for (i = 0; i < OCM_MAX_SIZE; i += 4) 294 asd_write_ocm_dword(asd_ha, i, 0); 295 296 /* Write Dir */ 297 asd_write_ocm_seg(asd_ha, &OCMDirInit, 0, 298 sizeof(struct asd_ocm_dir)); 299 300 /* Write Dir Entries */ 301 for (i = 0; i < OCM_INIT_DIR_ENTRIES; i++) 302 asd_write_ocm_seg(asd_ha, &OCMDirEntriesInit[i], 303 sizeof(struct asd_ocm_dir) + 304 (i * sizeof(struct asd_ocm_dir_ent)) 305 , sizeof(struct asd_ocm_dir_ent)); 306 307 } 308 309 static int 310 asd_hwi_check_ocm_access (struct asd_ha_struct *asd_ha) 311 { 312 struct pci_dev *pcidev = asd_ha->pcidev; 313 u32 reg; 314 int err = 0; 315 u32 v; 316 317 /* check if OCM has been initialized by BIOS */ 318 reg = asd_read_reg_dword(asd_ha, EXSICNFGR); 319 320 if (!(reg & OCMINITIALIZED)) { 321 err = pci_read_config_dword(pcidev, PCIC_INTRPT_STAT, &v); 322 if (err) { 323 asd_printk("couldn't access PCIC_INTRPT_STAT of %s\n", 324 pci_name(pcidev)); 325 goto out; 326 } 327 328 printk(KERN_INFO "OCM is not initialized by BIOS," 329 "reinitialize it and ignore it, current IntrptStatus" 330 "is 0x%x\n", v); 331 332 if (v) 333 err = pci_write_config_dword(pcidev, 334 PCIC_INTRPT_STAT, v); 335 if (err) { 336 asd_printk("couldn't write PCIC_INTRPT_STAT of %s\n", 337 pci_name(pcidev)); 338 goto out; 339 } 340 341 asd_hwi_initialize_ocm_dir(asd_ha); 342 343 } 344 out: 345 return err; 346 } 347 348 /** 349 * asd_read_ocm - read on chip memory (OCM) 350 * @asd_ha: pointer to the host adapter structure 351 */ 352 int asd_read_ocm(struct asd_ha_struct *asd_ha) 353 { 354 int err; 355 struct asd_ocm_dir *dir; 356 357 if (asd_hwi_check_ocm_access(asd_ha)) 358 return -1; 359 360 dir = kmalloc(sizeof(*dir), GFP_KERNEL); 361 if (!dir) { 362 asd_printk("no memory for ocm dir\n"); 363 return -ENOMEM; 364 } 365 366 err = asd_read_ocm_dir(asd_ha, dir, 0); 367 if (err) 368 goto out; 369 370 err = asd_get_bios_chim(asd_ha, dir); 371 out: 372 kfree(dir); 373 return err; 374 } 375 376 /* ---------- FLASH stuff ---------- */ 377 378 #define FLASH_RESET 0xF0 379 380 #define FLASH_SIZE 0x200000 381 #define FLASH_DIR_COOKIE "*** ADAPTEC FLASH DIRECTORY *** " 382 #define FLASH_NEXT_ENTRY_OFFS 0x2000 383 #define FLASH_MAX_DIR_ENTRIES 32 384 385 #define FLASH_DE_TYPE_MASK 0x3FFFFFFF 386 #define FLASH_DE_MS 0x120 387 #define FLASH_DE_CTRL_A_USER 0xE0 388 389 struct asd_flash_de { 390 __le32 type; 391 __le32 offs; 392 __le32 pad_size; 393 __le32 image_size; 394 __le32 chksum; 395 u8 _r[12]; 396 u8 version[32]; 397 } __attribute__ ((packed)); 398 399 struct asd_flash_dir { 400 u8 cookie[32]; 401 __le32 rev; /* 2 */ 402 __le32 chksum; 403 __le32 chksum_antidote; 404 __le32 bld; 405 u8 bld_id[32]; /* build id data */ 406 u8 ver_data[32]; /* date and time of build */ 407 __le32 ae_mask; 408 __le32 v_mask; 409 __le32 oc_mask; 410 u8 _r[20]; 411 struct asd_flash_de dir_entry[FLASH_MAX_DIR_ENTRIES]; 412 } __attribute__ ((packed)); 413 414 struct asd_manuf_sec { 415 char sig[2]; /* 'S', 'M' */ 416 u16 offs_next; 417 u8 maj; /* 0 */ 418 u8 min; /* 0 */ 419 u16 chksum; 420 u16 size; 421 u8 _r[6]; 422 u8 sas_addr[SAS_ADDR_SIZE]; 423 u8 pcba_sn[ASD_PCBA_SN_SIZE]; 424 /* Here start the other segments */ 425 u8 linked_list[0]; 426 } __attribute__ ((packed)); 427 428 struct asd_manuf_phy_desc { 429 u8 state; /* low 4 bits */ 430 #define MS_PHY_STATE_ENABLED 0 431 #define MS_PHY_STATE_REPORTED 1 432 #define MS_PHY_STATE_HIDDEN 2 433 u8 phy_id; 434 u16 _r; 435 u8 phy_control_0; /* mode 5 reg 0x160 */ 436 u8 phy_control_1; /* mode 5 reg 0x161 */ 437 u8 phy_control_2; /* mode 5 reg 0x162 */ 438 u8 phy_control_3; /* mode 5 reg 0x163 */ 439 } __attribute__ ((packed)); 440 441 struct asd_manuf_phy_param { 442 char sig[2]; /* 'P', 'M' */ 443 u16 next; 444 u8 maj; /* 0 */ 445 u8 min; /* 2 */ 446 u8 num_phy_desc; /* 8 */ 447 u8 phy_desc_size; /* 8 */ 448 u8 _r[3]; 449 u8 usage_model_id; 450 u32 _r2; 451 struct asd_manuf_phy_desc phy_desc[ASD_MAX_PHYS]; 452 } __attribute__ ((packed)); 453 454 #if 0 455 static const char *asd_sb_type[] = { 456 "unknown", 457 "SGPIO", 458 [2 ... 0x7F] = "unknown", 459 [0x80] = "ADPT_I2C", 460 [0x81 ... 0xFF] = "VENDOR_UNIQUExx" 461 }; 462 #endif 463 464 struct asd_ms_sb_desc { 465 u8 type; 466 u8 node_desc_index; 467 u8 conn_desc_index; 468 u8 _recvd[0]; 469 } __attribute__ ((packed)); 470 471 #if 0 472 static const char *asd_conn_type[] = { 473 [0 ... 7] = "unknown", 474 "SFF8470", 475 "SFF8482", 476 "SFF8484", 477 [0x80] = "PCIX_DAUGHTER0", 478 [0x81] = "SAS_DAUGHTER0", 479 [0x82 ... 0xFF] = "VENDOR_UNIQUExx" 480 }; 481 482 static const char *asd_conn_location[] = { 483 "unknown", 484 "internal", 485 "external", 486 "board_to_board", 487 }; 488 #endif 489 490 struct asd_ms_conn_desc { 491 u8 type; 492 u8 location; 493 u8 num_sideband_desc; 494 u8 size_sideband_desc; 495 u32 _resvd; 496 u8 name[16]; 497 struct asd_ms_sb_desc sb_desc[0]; 498 } __attribute__ ((packed)); 499 500 struct asd_nd_phy_desc { 501 u8 vp_attch_type; 502 u8 attch_specific[0]; 503 } __attribute__ ((packed)); 504 505 #if 0 506 static const char *asd_node_type[] = { 507 "IOP", 508 "IO_CONTROLLER", 509 "EXPANDER", 510 "PORT_MULTIPLIER", 511 "PORT_MULTIPLEXER", 512 "MULTI_DROP_I2C_BUS", 513 }; 514 #endif 515 516 struct asd_ms_node_desc { 517 u8 type; 518 u8 num_phy_desc; 519 u8 size_phy_desc; 520 u8 _resvd; 521 u8 name[16]; 522 struct asd_nd_phy_desc phy_desc[0]; 523 } __attribute__ ((packed)); 524 525 struct asd_ms_conn_map { 526 char sig[2]; /* 'M', 'C' */ 527 __le16 next; 528 u8 maj; /* 0 */ 529 u8 min; /* 0 */ 530 __le16 cm_size; /* size of this struct */ 531 u8 num_conn; 532 u8 conn_size; 533 u8 num_nodes; 534 u8 usage_model_id; 535 u32 _resvd; 536 struct asd_ms_conn_desc conn_desc[0]; 537 struct asd_ms_node_desc node_desc[0]; 538 } __attribute__ ((packed)); 539 540 struct asd_ctrla_phy_entry { 541 u8 sas_addr[SAS_ADDR_SIZE]; 542 u8 sas_link_rates; /* max in hi bits, min in low bits */ 543 u8 flags; 544 u8 sata_link_rates; 545 u8 _r[5]; 546 } __attribute__ ((packed)); 547 548 struct asd_ctrla_phy_settings { 549 u8 id0; /* P'h'y */ 550 u8 _r; 551 u16 next; 552 u8 num_phys; /* number of PHYs in the PCI function */ 553 u8 _r2[3]; 554 struct asd_ctrla_phy_entry phy_ent[ASD_MAX_PHYS]; 555 } __attribute__ ((packed)); 556 557 struct asd_ll_el { 558 u8 id0; 559 u8 id1; 560 __le16 next; 561 u8 something_here[0]; 562 } __attribute__ ((packed)); 563 564 static int asd_poll_flash(struct asd_ha_struct *asd_ha) 565 { 566 int c; 567 u8 d; 568 569 for (c = 5000; c > 0; c--) { 570 d = asd_read_reg_byte(asd_ha, asd_ha->hw_prof.flash.bar); 571 d ^= asd_read_reg_byte(asd_ha, asd_ha->hw_prof.flash.bar); 572 if (!d) 573 return 0; 574 udelay(5); 575 } 576 return -ENOENT; 577 } 578 579 static int asd_reset_flash(struct asd_ha_struct *asd_ha) 580 { 581 int err; 582 583 err = asd_poll_flash(asd_ha); 584 if (err) 585 return err; 586 asd_write_reg_byte(asd_ha, asd_ha->hw_prof.flash.bar, FLASH_RESET); 587 err = asd_poll_flash(asd_ha); 588 589 return err; 590 } 591 592 static inline int asd_read_flash_seg(struct asd_ha_struct *asd_ha, 593 void *buffer, u32 offs, int size) 594 { 595 asd_read_reg_string(asd_ha, buffer, asd_ha->hw_prof.flash.bar+offs, 596 size); 597 return 0; 598 } 599 600 /** 601 * asd_find_flash_dir - finds and reads the flash directory 602 * @asd_ha: pointer to the host adapter structure 603 * @flash_dir: pointer to flash directory structure 604 * 605 * If found, the flash directory segment will be copied to 606 * @flash_dir. Return 1 if found, 0 if not. 607 */ 608 static int asd_find_flash_dir(struct asd_ha_struct *asd_ha, 609 struct asd_flash_dir *flash_dir) 610 { 611 u32 v; 612 for (v = 0; v < FLASH_SIZE; v += FLASH_NEXT_ENTRY_OFFS) { 613 asd_read_flash_seg(asd_ha, flash_dir, v, 614 sizeof(FLASH_DIR_COOKIE)-1); 615 if (memcmp(flash_dir->cookie, FLASH_DIR_COOKIE, 616 sizeof(FLASH_DIR_COOKIE)-1) == 0) { 617 asd_ha->hw_prof.flash.dir_offs = v; 618 asd_read_flash_seg(asd_ha, flash_dir, v, 619 sizeof(*flash_dir)); 620 return 1; 621 } 622 } 623 return 0; 624 } 625 626 static int asd_flash_getid(struct asd_ha_struct *asd_ha) 627 { 628 int err = 0; 629 u32 reg; 630 631 reg = asd_read_reg_dword(asd_ha, EXSICNFGR); 632 633 if (pci_read_config_dword(asd_ha->pcidev, PCI_CONF_FLSH_BAR, 634 &asd_ha->hw_prof.flash.bar)) { 635 asd_printk("couldn't read PCI_CONF_FLSH_BAR of %s\n", 636 pci_name(asd_ha->pcidev)); 637 return -ENOENT; 638 } 639 asd_ha->hw_prof.flash.present = 1; 640 asd_ha->hw_prof.flash.wide = reg & FLASHW ? 1 : 0; 641 err = asd_reset_flash(asd_ha); 642 if (err) { 643 ASD_DPRINTK("couldn't reset flash(%d)\n", err); 644 return err; 645 } 646 return 0; 647 } 648 649 static u16 asd_calc_flash_chksum(u16 *p, int size) 650 { 651 u16 chksum = 0; 652 653 while (size-- > 0) 654 chksum += *p++; 655 656 return chksum; 657 } 658 659 660 static int asd_find_flash_de(struct asd_flash_dir *flash_dir, u32 entry_type, 661 u32 *offs, u32 *size) 662 { 663 int i; 664 struct asd_flash_de *de; 665 666 for (i = 0; i < FLASH_MAX_DIR_ENTRIES; i++) { 667 u32 type = le32_to_cpu(flash_dir->dir_entry[i].type); 668 669 type &= FLASH_DE_TYPE_MASK; 670 if (type == entry_type) 671 break; 672 } 673 if (i >= FLASH_MAX_DIR_ENTRIES) 674 return -ENOENT; 675 de = &flash_dir->dir_entry[i]; 676 *offs = le32_to_cpu(de->offs); 677 *size = le32_to_cpu(de->pad_size); 678 return 0; 679 } 680 681 static int asd_validate_ms(struct asd_manuf_sec *ms) 682 { 683 if (ms->sig[0] != 'S' || ms->sig[1] != 'M') { 684 ASD_DPRINTK("manuf sec: no valid sig(%c%c)\n", 685 ms->sig[0], ms->sig[1]); 686 return -ENOENT; 687 } 688 if (ms->maj != 0) { 689 asd_printk("unsupported manuf. sector. major version:%x\n", 690 ms->maj); 691 return -ENOENT; 692 } 693 ms->offs_next = le16_to_cpu((__force __le16) ms->offs_next); 694 ms->chksum = le16_to_cpu((__force __le16) ms->chksum); 695 ms->size = le16_to_cpu((__force __le16) ms->size); 696 697 if (asd_calc_flash_chksum((u16 *)ms, ms->size/2)) { 698 asd_printk("failed manuf sector checksum\n"); 699 } 700 701 return 0; 702 } 703 704 static int asd_ms_get_sas_addr(struct asd_ha_struct *asd_ha, 705 struct asd_manuf_sec *ms) 706 { 707 memcpy(asd_ha->hw_prof.sas_addr, ms->sas_addr, SAS_ADDR_SIZE); 708 return 0; 709 } 710 711 static int asd_ms_get_pcba_sn(struct asd_ha_struct *asd_ha, 712 struct asd_manuf_sec *ms) 713 { 714 memcpy(asd_ha->hw_prof.pcba_sn, ms->pcba_sn, ASD_PCBA_SN_SIZE); 715 asd_ha->hw_prof.pcba_sn[ASD_PCBA_SN_SIZE] = '\0'; 716 return 0; 717 } 718 719 /** 720 * asd_find_ll_by_id - find a linked list entry by its id 721 * @start: void pointer to the first element in the linked list 722 * @id0: the first byte of the id (offs 0) 723 * @id1: the second byte of the id (offs 1) 724 * 725 * @start has to be the _base_ element start, since the 726 * linked list entries's offset is from this pointer. 727 * Some linked list entries use only the first id, in which case 728 * you can pass 0xFF for the second. 729 */ 730 static void *asd_find_ll_by_id(void * const start, const u8 id0, const u8 id1) 731 { 732 struct asd_ll_el *el = start; 733 734 do { 735 switch (id1) { 736 default: 737 if (el->id1 == id1) 738 case 0xFF: 739 if (el->id0 == id0) 740 return el; 741 } 742 el = start + le16_to_cpu(el->next); 743 } while (el != start); 744 745 return NULL; 746 } 747 748 /** 749 * asd_ms_get_phy_params - get phy parameters from the manufacturing sector 750 * @asd_ha: pointer to the host adapter structure 751 * @manuf_sec: pointer to the manufacturing sector 752 * 753 * The manufacturing sector contans also the linked list of sub-segments, 754 * since when it was read, its size was taken from the flash directory, 755 * not from the structure size. 756 * 757 * HIDDEN phys do not count in the total count. REPORTED phys cannot 758 * be enabled but are reported and counted towards the total. 759 * ENABLED phys are enabled by default and count towards the total. 760 * The absolute total phy number is ASD_MAX_PHYS. hw_prof->num_phys 761 * merely specifies the number of phys the host adapter decided to 762 * report. E.g., it is possible for phys 0, 1 and 2 to be HIDDEN, 763 * phys 3, 4 and 5 to be REPORTED and phys 6 and 7 to be ENABLED. 764 * In this case ASD_MAX_PHYS is 8, hw_prof->num_phys is 5, and only 2 765 * are actually enabled (enabled by default, max number of phys 766 * enableable in this case). 767 */ 768 static int asd_ms_get_phy_params(struct asd_ha_struct *asd_ha, 769 struct asd_manuf_sec *manuf_sec) 770 { 771 int i; 772 int en_phys = 0; 773 int rep_phys = 0; 774 struct asd_manuf_phy_param *phy_param; 775 struct asd_manuf_phy_param dflt_phy_param; 776 777 phy_param = asd_find_ll_by_id(manuf_sec, 'P', 'M'); 778 if (!phy_param) { 779 ASD_DPRINTK("ms: no phy parameters found\n"); 780 ASD_DPRINTK("ms: Creating default phy parameters\n"); 781 dflt_phy_param.sig[0] = 'P'; 782 dflt_phy_param.sig[1] = 'M'; 783 dflt_phy_param.maj = 0; 784 dflt_phy_param.min = 2; 785 dflt_phy_param.num_phy_desc = 8; 786 dflt_phy_param.phy_desc_size = sizeof(struct asd_manuf_phy_desc); 787 for (i =0; i < ASD_MAX_PHYS; i++) { 788 dflt_phy_param.phy_desc[i].state = 0; 789 dflt_phy_param.phy_desc[i].phy_id = i; 790 dflt_phy_param.phy_desc[i].phy_control_0 = 0xf6; 791 dflt_phy_param.phy_desc[i].phy_control_1 = 0x10; 792 dflt_phy_param.phy_desc[i].phy_control_2 = 0x43; 793 dflt_phy_param.phy_desc[i].phy_control_3 = 0xeb; 794 } 795 796 phy_param = &dflt_phy_param; 797 798 } 799 800 if (phy_param->maj != 0) { 801 asd_printk("unsupported manuf. phy param major version:0x%x\n", 802 phy_param->maj); 803 return -ENOENT; 804 } 805 806 ASD_DPRINTK("ms: num_phy_desc: %d\n", phy_param->num_phy_desc); 807 asd_ha->hw_prof.enabled_phys = 0; 808 for (i = 0; i < phy_param->num_phy_desc; i++) { 809 struct asd_manuf_phy_desc *pd = &phy_param->phy_desc[i]; 810 switch (pd->state & 0xF) { 811 case MS_PHY_STATE_HIDDEN: 812 ASD_DPRINTK("ms: phy%d: HIDDEN\n", i); 813 continue; 814 case MS_PHY_STATE_REPORTED: 815 ASD_DPRINTK("ms: phy%d: REPORTED\n", i); 816 asd_ha->hw_prof.enabled_phys &= ~(1 << i); 817 rep_phys++; 818 continue; 819 case MS_PHY_STATE_ENABLED: 820 ASD_DPRINTK("ms: phy%d: ENABLED\n", i); 821 asd_ha->hw_prof.enabled_phys |= (1 << i); 822 en_phys++; 823 break; 824 } 825 asd_ha->hw_prof.phy_desc[i].phy_control_0 = pd->phy_control_0; 826 asd_ha->hw_prof.phy_desc[i].phy_control_1 = pd->phy_control_1; 827 asd_ha->hw_prof.phy_desc[i].phy_control_2 = pd->phy_control_2; 828 asd_ha->hw_prof.phy_desc[i].phy_control_3 = pd->phy_control_3; 829 } 830 asd_ha->hw_prof.max_phys = rep_phys + en_phys; 831 asd_ha->hw_prof.num_phys = en_phys; 832 ASD_DPRINTK("ms: max_phys:0x%x, num_phys:0x%x\n", 833 asd_ha->hw_prof.max_phys, asd_ha->hw_prof.num_phys); 834 ASD_DPRINTK("ms: enabled_phys:0x%x\n", asd_ha->hw_prof.enabled_phys); 835 return 0; 836 } 837 838 static int asd_ms_get_connector_map(struct asd_ha_struct *asd_ha, 839 struct asd_manuf_sec *manuf_sec) 840 { 841 struct asd_ms_conn_map *cm; 842 843 cm = asd_find_ll_by_id(manuf_sec, 'M', 'C'); 844 if (!cm) { 845 ASD_DPRINTK("ms: no connector map found\n"); 846 return 0; 847 } 848 849 if (cm->maj != 0) { 850 ASD_DPRINTK("ms: unsupported: connector map major version 0x%x" 851 "\n", cm->maj); 852 return -ENOENT; 853 } 854 855 /* XXX */ 856 857 return 0; 858 } 859 860 861 /** 862 * asd_process_ms - find and extract information from the manufacturing sector 863 * @asd_ha: pointer to the host adapter structure 864 * @flash_dir: pointer to the flash directory 865 */ 866 static int asd_process_ms(struct asd_ha_struct *asd_ha, 867 struct asd_flash_dir *flash_dir) 868 { 869 int err; 870 struct asd_manuf_sec *manuf_sec; 871 u32 offs, size; 872 873 err = asd_find_flash_de(flash_dir, FLASH_DE_MS, &offs, &size); 874 if (err) { 875 ASD_DPRINTK("Couldn't find the manuf. sector\n"); 876 goto out; 877 } 878 879 if (size == 0) 880 goto out; 881 882 err = -ENOMEM; 883 manuf_sec = kmalloc(size, GFP_KERNEL); 884 if (!manuf_sec) { 885 ASD_DPRINTK("no mem for manuf sector\n"); 886 goto out; 887 } 888 889 err = asd_read_flash_seg(asd_ha, (void *)manuf_sec, offs, size); 890 if (err) { 891 ASD_DPRINTK("couldn't read manuf sector at 0x%x, size 0x%x\n", 892 offs, size); 893 goto out2; 894 } 895 896 err = asd_validate_ms(manuf_sec); 897 if (err) { 898 ASD_DPRINTK("couldn't validate manuf sector\n"); 899 goto out2; 900 } 901 902 err = asd_ms_get_sas_addr(asd_ha, manuf_sec); 903 if (err) { 904 ASD_DPRINTK("couldn't read the SAS_ADDR\n"); 905 goto out2; 906 } 907 ASD_DPRINTK("manuf sect SAS_ADDR %llx\n", 908 SAS_ADDR(asd_ha->hw_prof.sas_addr)); 909 910 err = asd_ms_get_pcba_sn(asd_ha, manuf_sec); 911 if (err) { 912 ASD_DPRINTK("couldn't read the PCBA SN\n"); 913 goto out2; 914 } 915 ASD_DPRINTK("manuf sect PCBA SN %s\n", asd_ha->hw_prof.pcba_sn); 916 917 err = asd_ms_get_phy_params(asd_ha, manuf_sec); 918 if (err) { 919 ASD_DPRINTK("ms: couldn't get phy parameters\n"); 920 goto out2; 921 } 922 923 err = asd_ms_get_connector_map(asd_ha, manuf_sec); 924 if (err) { 925 ASD_DPRINTK("ms: couldn't get connector map\n"); 926 goto out2; 927 } 928 929 out2: 930 kfree(manuf_sec); 931 out: 932 return err; 933 } 934 935 static int asd_process_ctrla_phy_settings(struct asd_ha_struct *asd_ha, 936 struct asd_ctrla_phy_settings *ps) 937 { 938 int i; 939 for (i = 0; i < ps->num_phys; i++) { 940 struct asd_ctrla_phy_entry *pe = &ps->phy_ent[i]; 941 942 if (!PHY_ENABLED(asd_ha, i)) 943 continue; 944 if (*(u64 *)pe->sas_addr == 0) { 945 asd_ha->hw_prof.enabled_phys &= ~(1 << i); 946 continue; 947 } 948 /* This is the SAS address which should be sent in IDENTIFY. */ 949 memcpy(asd_ha->hw_prof.phy_desc[i].sas_addr, pe->sas_addr, 950 SAS_ADDR_SIZE); 951 asd_ha->hw_prof.phy_desc[i].max_sas_lrate = 952 (pe->sas_link_rates & 0xF0) >> 4; 953 asd_ha->hw_prof.phy_desc[i].min_sas_lrate = 954 (pe->sas_link_rates & 0x0F); 955 asd_ha->hw_prof.phy_desc[i].max_sata_lrate = 956 (pe->sata_link_rates & 0xF0) >> 4; 957 asd_ha->hw_prof.phy_desc[i].min_sata_lrate = 958 (pe->sata_link_rates & 0x0F); 959 asd_ha->hw_prof.phy_desc[i].flags = pe->flags; 960 ASD_DPRINTK("ctrla: phy%d: sas_addr: %llx, sas rate:0x%x-0x%x," 961 " sata rate:0x%x-0x%x, flags:0x%x\n", 962 i, 963 SAS_ADDR(asd_ha->hw_prof.phy_desc[i].sas_addr), 964 asd_ha->hw_prof.phy_desc[i].max_sas_lrate, 965 asd_ha->hw_prof.phy_desc[i].min_sas_lrate, 966 asd_ha->hw_prof.phy_desc[i].max_sata_lrate, 967 asd_ha->hw_prof.phy_desc[i].min_sata_lrate, 968 asd_ha->hw_prof.phy_desc[i].flags); 969 } 970 971 return 0; 972 } 973 974 /** 975 * asd_process_ctrl_a_user - process CTRL-A user settings 976 * @asd_ha: pointer to the host adapter structure 977 * @flash_dir: pointer to the flash directory 978 */ 979 static int asd_process_ctrl_a_user(struct asd_ha_struct *asd_ha, 980 struct asd_flash_dir *flash_dir) 981 { 982 int err, i; 983 u32 offs, size; 984 struct asd_ll_el *el; 985 struct asd_ctrla_phy_settings *ps; 986 struct asd_ctrla_phy_settings dflt_ps; 987 988 err = asd_find_flash_de(flash_dir, FLASH_DE_CTRL_A_USER, &offs, &size); 989 if (err) { 990 ASD_DPRINTK("couldn't find CTRL-A user settings section\n"); 991 ASD_DPRINTK("Creating default CTRL-A user settings section\n"); 992 993 dflt_ps.id0 = 'h'; 994 dflt_ps.num_phys = 8; 995 for (i =0; i < ASD_MAX_PHYS; i++) { 996 memcpy(dflt_ps.phy_ent[i].sas_addr, 997 asd_ha->hw_prof.sas_addr, SAS_ADDR_SIZE); 998 dflt_ps.phy_ent[i].sas_link_rates = 0x98; 999 dflt_ps.phy_ent[i].flags = 0x0; 1000 dflt_ps.phy_ent[i].sata_link_rates = 0x0; 1001 } 1002 1003 size = sizeof(struct asd_ctrla_phy_settings); 1004 ps = &dflt_ps; 1005 } 1006 1007 if (size == 0) 1008 goto out; 1009 1010 err = -ENOMEM; 1011 el = kmalloc(size, GFP_KERNEL); 1012 if (!el) { 1013 ASD_DPRINTK("no mem for ctrla user settings section\n"); 1014 goto out; 1015 } 1016 1017 err = asd_read_flash_seg(asd_ha, (void *)el, offs, size); 1018 if (err) { 1019 ASD_DPRINTK("couldn't read ctrla phy settings section\n"); 1020 goto out2; 1021 } 1022 1023 err = -ENOENT; 1024 ps = asd_find_ll_by_id(el, 'h', 0xFF); 1025 if (!ps) { 1026 ASD_DPRINTK("couldn't find ctrla phy settings struct\n"); 1027 goto out2; 1028 } 1029 1030 err = asd_process_ctrla_phy_settings(asd_ha, ps); 1031 if (err) { 1032 ASD_DPRINTK("couldn't process ctrla phy settings\n"); 1033 goto out2; 1034 } 1035 out2: 1036 kfree(el); 1037 out: 1038 return err; 1039 } 1040 1041 /** 1042 * asd_read_flash - read flash memory 1043 * @asd_ha: pointer to the host adapter structure 1044 */ 1045 int asd_read_flash(struct asd_ha_struct *asd_ha) 1046 { 1047 int err; 1048 struct asd_flash_dir *flash_dir; 1049 1050 err = asd_flash_getid(asd_ha); 1051 if (err) 1052 return err; 1053 1054 flash_dir = kmalloc(sizeof(*flash_dir), GFP_KERNEL); 1055 if (!flash_dir) 1056 return -ENOMEM; 1057 1058 err = -ENOENT; 1059 if (!asd_find_flash_dir(asd_ha, flash_dir)) { 1060 ASD_DPRINTK("couldn't find flash directory\n"); 1061 goto out; 1062 } 1063 1064 if (le32_to_cpu(flash_dir->rev) != 2) { 1065 asd_printk("unsupported flash dir version:0x%x\n", 1066 le32_to_cpu(flash_dir->rev)); 1067 goto out; 1068 } 1069 1070 err = asd_process_ms(asd_ha, flash_dir); 1071 if (err) { 1072 ASD_DPRINTK("couldn't process manuf sector settings\n"); 1073 goto out; 1074 } 1075 1076 err = asd_process_ctrl_a_user(asd_ha, flash_dir); 1077 if (err) { 1078 ASD_DPRINTK("couldn't process CTRL-A user settings\n"); 1079 goto out; 1080 } 1081 1082 out: 1083 kfree(flash_dir); 1084 return err; 1085 } 1086