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