* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) @ 2003-03-12 0:25 Thayne Harbaugh 2003-03-12 15:44 ` John Burch 2003-03-12 16:27 ` Steve Wahl 0 siblings, 2 replies; 20+ messages in thread From: Thayne Harbaugh @ 2003-03-12 0:25 UTC (permalink / raw) To: linux-mtd --=-bK4IZ7vhYqXn1yFR9yRW Content-Type: text/plain Content-Transfer-Encoding: quoted-printable For some reason I am confused: I get the feeling that what I'm trying to understand is obvious - I just can't see the forest for the trees. Will someone help me understand? cfi_cmdset_0002.c has several functions that use dq5 and dq6 for monitoring the status of erase and write operations: dq6 =3D CMD(1<<6); dq5 =3D CMD(1<<5); Apparently, from the code dq6 toggles during erase/read operations and dq5 is low until the erase/read operation times out and then goes high (somewhat like a watchdog bit). My understanding,@least for the SST 49LF040 and PMC Pm49L004 is that dq6 toggles during erase/write and dq7 is inverted until the erase/write operation completes. This causes me to expect to see the following code rather than what is written above (not to mention that most everything in do_write_one_word() should be adapted for dq7 invert): dq7 =3D CMD(1<<7); /* invert */ dq6 =3D CMD(1<<6); /* toggle */ The differences give me the feeling that there really are two different classes of cfi_cmdset_0002 - those devices that have a dq5 watchdog and those devices that don't have the watchdog, but have a bit inverter on dq7. Am I not understanding what happens on bits 0-5 during an erase/write operation? The PMC and SST chips don't mention a thing about dq5 behavior. If they don't have the dq5 watchdog timer then they will behave in an undefined way (depending on the state of bit 5 in the written word) with the current dq5 checking. This explains the many warnings I see with the SST and PMC chips in do_write_oneword(), "Warning: DQ5 raised while program operation was in progress, however operation completed OK" Around here we refer to this as the "Dairy Queen 5" warning. Obviosly, during an erase that completes prior to dq5 being read-back, dq5 will be high and the current algorithm is erroneously correct. This can explain why I have not seen the same message in do_erase_oneblock(). Furthermore, the SST documentation on page 10 refers to "spurios rejection" of good writes - differentiating between a write that succeeds that appears to fail and a write that fails. It says that a write that appears to fail needs to be read back two more times successfully to filter out spurious rejection. Comments? What should change to improve the operation completion check? Should cfi_cmdset_0002 be adapted to handle multiple types of polling or should another command set be written? --=20 Thayne Harbaugh Linux Networx --=-bK4IZ7vhYqXn1yFR9yRW Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6 (GNU/Linux) Comment: For info see http://www.gnupg.org iD8DBQA+bn5rfsBPTKE6HMkRAs4BAJ9X+2ohh6yJj0pl/bhoePQkSDI+CQCfacc7 o6FfFw5wUv1dT06gFCcaGnY= =+ZHx -----END PGP SIGNATURE----- --=-bK4IZ7vhYqXn1yFR9yRW-- ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-12 0:25 DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) Thayne Harbaugh @ 2003-03-12 15:44 ` John Burch 2003-03-12 16:35 ` Thayne Harbaugh 2003-03-12 16:27 ` Steve Wahl 1 sibling, 1 reply; 20+ messages in thread From: John Burch @ 2003-03-12 15:44 UTC (permalink / raw) To: linux-mtd > -----Original Message----- > From: linux-mtd-admin at lists.infradead.org=20 > [mailto:linux-mtd-admin at lists.infradead.org] On Behalf Of=20 > Thayne Harbaugh > Sent: Tuesday, March 11, 2003 7:25 PM > To: linux-mtd at lists.infradead.org > Subject: DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) >=20 >=20 > For some reason I am confused: I get the feeling that what=20 > I'm trying to understand is obvious - I just can't see the=20 > forest for the trees. Will someone help me understand? >=20 > cfi_cmdset_0002.c has several functions that use dq5 and dq6=20 > for monitoring the status of erase and write operations: >=20 > dq6 =3D CMD(1<<6); > dq5 =3D CMD(1<<5); >=20 > Apparently, from the code dq6 toggles during erase/read=20 > operations and dq5 is low until the erase/read operation=20 > times out and then goes high (somewhat like a watchdog bit). >=20 > My understanding, at least for the SST 49LF040 and PMC=20 > Pm49L004 is that dq6 toggles during erase/write and dq7 is=20 > inverted until the erase/write operation completes. This=20 > causes me to expect to see the following code rather than=20 > what is written above (not to mention that most everything in=20 > do_write_one_word() should be adapted for dq7 invert): >=20 > dq7 =3D CMD(1<<7); /* invert */ > dq6 =3D CMD(1<<6); /* toggle */ >=20 > The differences give me the feeling that there really are two=20 > different classes of cfi_cmdset_0002 - those devices that=20 > have a dq5 watchdog and those devices that don't have the=20 > watchdog, but have a bit inverter on dq7. >=20 > Am I not understanding what happens on bits 0-5 during an=20 > erase/write operation? The PMC and SST chips don't mention a=20 > thing about dq5 behavior. If they don't have the dq5=20 > watchdog timer then they will behave in an undefined way=20 > (depending on the state of bit 5 in the written word) with=20 > the current dq5 checking. This explains the many warnings I=20 > see with the SST and PMC chips in do_write_oneword(), >=20 > "Warning: DQ5 raised while program operation was in progress,=20 > however operation completed OK" >=20 > Around here we refer to this as the "Dairy Queen 5" warning. >=20 > Obviosly, during an erase that completes prior to dq5 being=20 > read-back, dq5 will be high and the current algorithm is=20 > erroneously correct. This can explain why I have not seen=20 > the same message in do_erase_oneblock(). >=20 > Furthermore, the SST documentation on page 10 refers to=20 > "spurios rejection" of good writes - differentiating between=20 > a write that succeeds that appears to fail and a write that=20 > fails. It says that a write that appears to fail needs to be=20 > read back two more times successfully to filter out spurious=20 > rejection. >=20 > Comments? What should change to improve the operation=20 > completion check? Should cfi_cmdset_0002 be adapted to=20 > handle multiple types of polling or should another command=20 > set be written? The attached app note from AMD explains things in detail relative to AMD devices. I'm not sure how it applies to PMC and SST devices or not. It seems as though DQ7 polling or DQ6 polling, by themselves, give a simple pass/fail/busy result; while DQ7 or DQ6 polling in combination with DQ5 and DQ2 polling give pass/fail/ erase suspended/timeout/busy result. John >=20 > --=20 > Thayne Harbaugh > Linux Networx >=20 ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-12 15:44 ` John Burch @ 2003-03-12 16:35 ` Thayne Harbaugh 0 siblings, 0 replies; 20+ messages in thread From: Thayne Harbaugh @ 2003-03-12 16:35 UTC (permalink / raw) To: linux-mtd --=-SCiByEcspzKD8yaWvDLo Content-Type: text/plain Content-Transfer-Encoding: quoted-printable On Wed, 2003-03-12 at 08:44, John Burch wrote: > > -----Original Message----- > > From: linux-mtd-admin at lists.infradead.org=20 > > [mailto:linux-mtd-admin at lists.infradead.org] On Behalf Of=20 > > Thayne Harbaugh > > Sent: Tuesday, March 11, 2003 7:25 PM > > To: linux-mtd at lists.infradead.org > > Subject: DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) > >=20 > >=20 <snip> >=20 > The attached app note Attachment? > from AMD explains things in detail relative > to AMD devices. <snip> >=20 > John >=20 > >=20 > > --=20 > > Thayne Harbaugh > > Linux Networx > >=20 >=20 >=20 > ______________________________________________________ > Linux MTD discussion mailing list > http://lists.infradead.org/mailman/listinfo/linux-mtd/ --=20 Thayne Harbaugh Linux Networx --=-SCiByEcspzKD8yaWvDLo Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6 (GNU/Linux) Comment: For info see http://www.gnupg.org iD8DBQA+b2HWfsBPTKE6HMkRAhHHAJ9pblnTYxLLUr10W6LJtazo28wKmgCfRHFy sqjeNuPDPxFm0yhfrss2E8o= =aEVN -----END PGP SIGNATURE----- --=-SCiByEcspzKD8yaWvDLo-- ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-12 0:25 DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) Thayne Harbaugh 2003-03-12 15:44 ` John Burch @ 2003-03-12 16:27 ` Steve Wahl 2003-03-12 17:12 ` John Burch 2003-03-17 15:40 ` Thayne Harbaugh 1 sibling, 2 replies; 20+ messages in thread From: Steve Wahl @ 2003-03-12 16:27 UTC (permalink / raw) To: linux-mtd Thayne, I have a patch that I was given permission to check in, but never got around to it, that covers a similar "DQ5 raised" problem. I would wager you are running into the same problem I did, and that your chips compatibly support DQ5, if not as a watchdog, at least by holding it low while programming. Can you look at my previous posts on this, try my patch (if you don't have interleaved chips -- contact me if you do), and see if it works for you? http://lists.infradead.org/pipermail/linux-mtd/2003-January/006780.html --> Steve On Tue, Mar 11, 2003 at 05:25:15PM -0700, Thayne Harbaugh wrote: > For some reason I am confused: I get the feeling that what I'm trying to > understand is obvious - I just can't see the forest for the trees. Will > someone help me understand? > > cfi_cmdset_0002.c has several functions that use dq5 and dq6 for > monitoring the status of erase and write operations: > > dq6 = CMD(1<<6); > dq5 = CMD(1<<5); > > Apparently, from the code dq6 toggles during erase/read operations and > dq5 is low until the erase/read operation times out and then goes high > (somewhat like a watchdog bit). > > My understanding, at least for the SST 49LF040 and PMC Pm49L004 is that > dq6 toggles during erase/write and dq7 is inverted until the erase/write > operation completes. This causes me to expect to see the following code > rather than what is written above (not to mention that most everything > in do_write_one_word() should be adapted for dq7 invert): > > dq7 = CMD(1<<7); /* invert */ > dq6 = CMD(1<<6); /* toggle */ > > The differences give me the feeling that there really are two different > classes of cfi_cmdset_0002 - those devices that have a dq5 watchdog and > those devices that don't have the watchdog, but have a bit inverter on > dq7. > > Am I not understanding what happens on bits 0-5 during an erase/write > operation? The PMC and SST chips don't mention a thing about dq5 > behavior. If they don't have the dq5 watchdog timer then they will > behave in an undefined way (depending on the state of bit 5 in the > written word) with the current dq5 checking. This explains the many > warnings I see with the SST and PMC chips in do_write_oneword(), > > "Warning: DQ5 raised while program operation was in progress, however > operation completed OK" > > Around here we refer to this as the "Dairy Queen 5" warning. > > Obviosly, during an erase that completes prior to dq5 being read-back, > dq5 will be high and the current algorithm is erroneously correct. This > can explain why I have not seen the same message in do_erase_oneblock(). > > Furthermore, the SST documentation on page 10 refers to "spurios > rejection" of good writes - differentiating between a write that > succeeds that appears to fail and a write that fails. It says that a > write that appears to fail needs to be read back two more times > successfully to filter out spurious rejection. > > Comments? What should change to improve the operation completion > check? Should cfi_cmdset_0002 be adapted to handle multiple types of > polling or should another command set be written? > > -- > Thayne Harbaugh > Linux Networx ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-12 16:27 ` Steve Wahl @ 2003-03-12 17:12 ` John Burch 2003-03-12 21:43 ` Steve Wahl 2003-03-17 15:40 ` Thayne Harbaugh 1 sibling, 1 reply; 20+ messages in thread From: John Burch @ 2003-03-12 17:12 UTC (permalink / raw) To: linux-mtd This is a multi-part message in MIME format. ------=_NextPart_000_0028_01C2E890.9DBAE0C0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: quoted-printable AMD's own method from code they provide is shown below... By the way, AMD specifically mentions having to check DQ6/7 again after DQ5=3D1 because of the possibility that DQ5=3D1 simultaneous with toggling stopping. The app note I referred to before (attached this time) describes this in some detail. The status register (including DQ5) won't reflect actual data until a reset command is issued, so I think the concern about DQ5=3D1 because erased data (0xff) is read instead of status is not valid. John >From AMD's cfiflash.c: /*********************************************************************/ /* Flash_status utilizes the DQ6, DQ5, and DQ3 polling algorithms */ /* described in the flash data book. It can quickly ascertain the */ /* operational status of the flash device, and return an */ /* appropriate status code (defined in flash.h) */ /*********************************************************************/ =20 int flash_status(word far *fp) { unsigned char d, t; int retry =3D 1; again: d =3D *fp; /* read data */ t =3D d ^ *fp; /* read it again and see what toggled */ if (t =3D=3D 0) { /* no toggles, nothing's happening */ return STATUS_READY; } else if (t =3D=3D 0x04) { /* erase-suspend */ if (retry--) goto again; /* may have been write completion */ return STATUS_ERSUSP; } else if (t & 0x40) { if (d & 0x20) { /* timeout */ return STATUS_TIMEOUT; } else { return STATUS_BUSY; } } if (retry--) goto again; /* may have been write completion */ return STATUS_ERROR; } > -----Original Message----- > From: linux-mtd-admin at lists.infradead.org=20 > [mailto:linux-mtd-admin at lists.infradead.org] On Behalf Of Steve Wahl > Sent: Wednesday, March 12, 2003 11:28 AM > To: Thayne Harbaugh > Cc: linux-mtd at lists.infradead.org > Subject: Re: DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy=20 > Queen 5 warning) >=20 >=20 > Thayne,=20 >=20 > I have a patch that I was given permission to check in, but=20 > never got around to it, that covers a similar "DQ5 raised" problem. >=20 > I would wager you are running into the same problem I did,=20 > and that your chips compatibly support DQ5, if not as a=20 > watchdog, at least by holding it low while programming. >=20 > Can you look at my previous posts on this, try my patch (if=20 > you don't have interleaved chips -- contact me if you do),=20 > and see if it works for you? >=20 > http://lists.infradead.org/pipermail/linux-mtd/2003-January/00 > 6780.html >=20 > --> Steve >=20 >=20 > On Tue, Mar 11, 2003 at 05:25:15PM -0700, Thayne Harbaugh wrote: > > For some reason I am confused: I get the feeling that what=20 > I'm trying=20 > > to understand is obvious - I just can't see the forest for=20 > the trees. =20 > > Will someone help me understand? > >=20 > > cfi_cmdset_0002.c has several functions that use dq5 and dq6 for=20 > > monitoring the status of erase and write operations: > >=20 > > dq6 =3D CMD(1<<6); > > dq5 =3D CMD(1<<5); > >=20 > > Apparently, from the code dq6 toggles during erase/read=20 > operations and=20 > > dq5 is low until the erase/read operation times out and=20 > then goes high=20 > > (somewhat like a watchdog bit). > >=20 > > My understanding, at least for the SST 49LF040 and PMC Pm49L004 is=20 > > that dq6 toggles during erase/write and dq7 is inverted until the=20 > > erase/write operation completes. This causes me to expect=20 > to see the=20 > > following code rather than what is written above (not to=20 > mention that=20 > > most everything in do_write_one_word() should be adapted for dq7=20 > > invert): > >=20 > > dq7 =3D CMD(1<<7); /* invert */ > > dq6 =3D CMD(1<<6); /* toggle */ > >=20 > > The differences give me the feeling that there really are two=20 > > different classes of cfi_cmdset_0002 - those devices that=20 > have a dq5=20 > > watchdog and those devices that don't have the watchdog, but have a=20 > > bit inverter on dq7. > >=20 > > Am I not understanding what happens on bits 0-5 during an=20 > erase/write=20 > > operation? The PMC and SST chips don't mention a thing about dq5=20 > > behavior. If they don't have the dq5 watchdog timer then they will=20 > > behave in an undefined way (depending on the state of bit 5 in the=20 > > written word) with the current dq5 checking. This explains=20 > the many=20 > > warnings I see with the SST and PMC chips in do_write_oneword(), > >=20 > > "Warning: DQ5 raised while program operation was in=20 > progress, however=20 > > operation completed OK" > >=20 > > Around here we refer to this as the "Dairy Queen 5" warning. > >=20 > > Obviosly, during an erase that completes prior to dq5 being=20 > read-back,=20 > > dq5 will be high and the current algorithm is erroneously correct. =20 > > This can explain why I have not seen the same message in=20 > > do_erase_oneblock(). > >=20 > > Furthermore, the SST documentation on page 10 refers to "spurios=20 > > rejection" of good writes - differentiating between a write that=20 > > succeeds that appears to fail and a write that fails. It=20 > says that a=20 > > write that appears to fail needs to be read back two more times=20 > > successfully to filter out spurious rejection. > >=20 > > Comments? What should change to improve the operation completion=20 > > check? Should cfi_cmdset_0002 be adapted to handle=20 > multiple types of=20 > > polling or should another command set be written? > >=20 > > -- > > Thayne Harbaugh > > Linux Networx >=20 >=20 >=20 > ______________________________________________________ > Linux MTD discussion mailing list > http://lists.infradead.org/mailman/listinfo/linux-mtd/ >=20 ------=_NextPart_000_0028_01C2E890.9DBAE0C0 Content-Type: application/pdf; name="22152.pdf" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="22152.pdf" JVBERi0xLjINJeLjz9MNCjQ0IDAgb2JqDTw8IA0vTGluZWFyaXplZCAxIA0vTyA0NiANL0ggWyA5 ODIgMzEwIF0gDS9MIDUyMTQ4IA0vRSAxMjk0NCANL04gMTAgDS9UIDUxMTUwIA0+PiANZW5kb2Jq DSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICB4cmVmDTQ0IDI5IA0wMDAwMDAwMDE2IDAwMDAwIG4NCjAwMDAwMDA5MjcgMDAwMDAgbg0KMDAw MDAwMTI5MiAwMDAwMCBuDQowMDAwMDAxNDk5IDAwMDAwIG4NCjAwMDAwMDE2NDcgMDAwMDAgbg0K MDAwMDAwMTczNCAwMDAwMCBuDQowMDAwMDAxODI2IDAwMDAwIG4NCjAwMDAwMDE4NDggMDAwMDAg bg0KMDAwMDAwMzAzOCAwMDAwMCBuDQowMDAwMDAzMDYwIDAwMDAwIG4NCjAwMDAwMDQyNjUgMDAw MDAgbg0KMDAwMDAwNDI4NyAwMDAwMCBuDQowMDAwMDA1NDI5IDAwMDAwIG4NCjAwMDAwMDU0NTEg MDAwMDAgbg0KMDAwMDAwNjU1NyAwMDAwMCBuDQowMDAwMDA2NTc5IDAwMDAwIG4NCjAwMDAwMDc3 MzUgMDAwMDAgbg0KMDAwMDAwNzc1NyAwMDAwMCBuDQowMDAwMDA4OTMyIDAwMDAwIG4NCjAwMDAw MTAxNTcgMDAwMDAgbg0KMDAwMDAxMDI2NyAwMDAwMCBuDQowMDAwMDEwMzcyIDAwMDAwIG4NCjAw MDAwMTAzOTQgMDAwMDAgbg0KMDAwMDAxMTYxMiAwMDAwMCBuDQowMDAwMDExNjMzIDAwMDAwIG4N CjAwMDAwMTI2MzggMDAwMDAgbg0KMDAwMDAxMjcxNSAwMDAwMCBuDQowMDAwMDAwOTgyIDAwMDAw IG4NCjAwMDAwMDEyNzEgMDAwMDAgbg0KdHJhaWxlcg08PA0vU2l6ZSA3Mw0vSW5mbyA0MyAwIFIg DS9Sb290IDQ1IDAgUiANL1ByZXYgNTExNDAgDS9JRFs8NDM3OGE5NjEyNjUxNGQ2Mjc0NGRhMGFh ZTlkYjU4NzU+PDQzNzhhOTYxMjY1MTRkNjI3NDRkYTBhYWU5ZGI1ODc1Pl0NPj4Nc3RhcnR4cmVm DTANJSVFT0YNICAgICANNDUgMCBvYmoNPDwgDS9UeXBlIC9DYXRhbG9nIA0vUGFnZXMgNDIgMCBS IA0+PiANZW5kb2JqDTcxIDAgb2JqDTw8IC9TIDE2NSAvRmlsdGVyIC9GbGF0ZURlY29kZSAvTGVu Z3RoIDcyIDAgUiA+PiANc3RyZWFtDQpIiWNgYGAGomsMrAwM7NYMfAwIwMfAAhRlYeDY4MLI4CDA MO3Eoy37QwRUYmIEcxqymVQYGMra2pZOAyllklGt4ag597u7o/rsBztu67cfDJ3CD/zQdAayLJ1+ PPtkmL1jx9E99xkY0jIaWCMaGAQ7GhglGhiBlJBGA6OSS0eDcQejoFJHg2tEA6Y9QKDKwLCnB0hL ArEcWESUgVvc8Y8iSwGzigPPAgbDFobDF5ilD/A0TWtM0WKQjGKQO2DBrhggf/WrG8Q/ALOLQEsN ZW5kc3RyZWFtDWVuZG9iag03MiAwIG9iag0yMDQgDWVuZG9iag00NiAwIG9iag08PCANL1R5cGUg L1BhZ2UgDS9QYXJlbnQgNDIgMCBSIA0vUmVzb3VyY2VzIDQ3IDAgUiANL0NvbnRlbnRzIFsgNTEg MCBSIDUzIDAgUiA1NSAwIFIgNTcgMCBSIDU5IDAgUiA2MSAwIFIgNjYgMCBSIDY4IDAgUiBdIA0v TWVkaWFCb3ggWyAwIDAgNjEyIDc5MiBdIA0vQ3JvcEJveCBbIDAgMCA2MTIgNzkyIF0gDS9Sb3Rh dGUgMCANPj4gDWVuZG9iag00NyAwIG9iag08PCANL1Byb2NTZXQgWyAvUERGIC9UZXh0IF0gDS9G b250IDw8IC9GMSA0OCAwIFIgL0YyIDQ5IDAgUiAvRjMgNjQgMCBSIC9GNCA2MyAwIFIgPj4gDS9F eHRHU3RhdGUgPDwgL0dTMSA3MCAwIFIgL0dTMiA2OSAwIFIgPj4gDT4+IA1lbmRvYmoNNDggMCBv YmoNPDwgDS9UeXBlIC9Gb250IA0vU3VidHlwZSAvVHlwZTEgDS9OYW1lIC9GMSANL0Jhc2VGb250 IC9IZWx2ZXRpY2EgDT4+IA1lbmRvYmoNNDkgMCBvYmoNPDwgDS9UeXBlIC9Gb250IA0vU3VidHlw ZSAvVHlwZTEgDS9OYW1lIC9GMiANL0Jhc2VGb250IC9IZWx2ZXRpY2EtQm9sZCANPj4gDWVuZG9i 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 LO6QiIwGbpBAwC5OM67ssIjDnRS5gyDLDTnRIMcxKxIyjh0yq2xa5QXByGUZN6gwZoShaBoKGLSu AvwiCi4oUBuFLjTgGySiIMNExvRlHrlRgR0gEAoBSGjnKfLw2DSsLjPLFiBxcFzfxmhrct3PqHQE vsaSu+tCyeFAbB0hKOtY+zqjO8sdS+rCcOaFAhSnEkAyg9AUBjOLLrguVTzuhMZocGDfuCitZOzW kBBQGtcOo5wiymPE2TXDbFw/HURPej8RVzLsOOyNrqQnEg3V+6oQCZEl6wleacx/cVi2Ojqa2dOa 51RPNrz5PNsUHbqjhoFLszhA4pMW7I5uS1qlowGijqjb2NxDhNS2i2k8AVVSDLvVqChlQNshRWQY qPbrjBnXD9hi52PBRdGEBaj6vhlRimJSEFyZxkEdTCrb30ZYjiOUlL6acNupqXYljLlNKRyRlFoY XajcIMG2Hz9PVYW0jDjW67IZXC5TnOIGMj1451fYI67jMWo8ELkj76ONALshA2uCC5Eujuc/0tce 58scpDD3uclatTvJmCLDwVJ85v7tBa4zETOjFGcNoXUzbLCUi4FOyVNlez7ZhzebZiNY4nZmLBRj CS413+OpGjUI5EFGSMV36rVJstT9tbXehh3/ghB4eOY94+Q5Gk/mOz505AUIoqIEOKBNY1yEBoGj XT2GQZhkFwcBAG1ThpIAyoEK4VBAG59JrVpAgU2DMgraiCA0fqqoHLaiVkCM+AoKL54AvrgIDWAw MG1PxfnAts0DwFBXf/BU18F35mbgUaEGJtSCQNf1BAgUEwFPoAU+qErSIDG0cU/J+j9n8QvhC/6A ENYBQ6aQDhOr9YEwLhbA5/YCoIwyhpDYhER4kw7g67SIEIohxUcUDaJDDoUl0hYnWJ0MIJECCE+Y BRqTSGmjhG41cAoqg1VcbZtBuk+EBA1lbmRzdHJlYW0NZW5kb2JqDTYyIDAgb2JqDTw8IA0vVHlw ZSAvRW5jb2RpbmcgDS9EaWZmZXJlbmNlcyBbIDM5IC9xdW90ZXNpbmdsZSA5NiAvZ3JhdmUgMTMw IC9xdW90ZXNpbmdsYmFzZSAvZmxvcmluIC9xdW90ZWRibGJhc2UgDS9lbGxpcHNpcyAvZGFnZ2Vy IC9kYWdnZXJkYmwgL2NpcmN1bWZsZXggL3BlcnRob3VzYW5kIC9TY2Fyb24gL2d1aWxzaW5nbGxl ZnQgDS9PRSAxNDUgL3F1b3RlbGVmdCAvcXVvdGVyaWdodCAvcXVvdGVkYmxsZWZ0IC9xdW90ZWRi bHJpZ2h0IC9idWxsZXQgDS9lbmRhc2ggL2VtZGFzaCAvdGlsZGUgL3RyYWRlbWFyayAvc2Nhcm9u IC9ndWlsc2luZ2xyaWdodCAvb2UgL2RvdGxlc3NpIA0xNTkgL1lkaWVyZXNpcyAxNjQgL2N1cnJl bmN5IDE2NiAvYnJva2VuYmFyIDE2OCAvZGllcmVzaXMgL2NvcHlyaWdodCANL29yZGZlbWluaW5l IDE3MiAvbG9naWNhbG5vdCAxNzQgL3JlZ2lzdGVyZWQgL21hY3JvbiAvcmluZyAvcGx1c21pbnVz IA0vdHdvc3VwZXJpb3IgL3RocmVlc3VwZXJpb3IgL2FjdXRlIC9tdSAxODMgL3BlcmlvZGNlbnRl cmVkIC9jZWRpbGxhIA0vb25lc3VwZXJpb3IgL29yZG1hc2N1bGluZSAxODggL29uZXF1YXJ0ZXIg L29uZWhhbGYgL3RocmVlcXVhcnRlcnMgDTE5MiAvQWdyYXZlIC9BYWN1dGUgL0FjaXJjdW1mbGV4 IC9BdGlsZGUgL0FkaWVyZXNpcyAvQXJpbmcgL0FFIC9DY2VkaWxsYSANL0VncmF2ZSAvRWFjdXRl IC9FY2lyY3VtZmxleCAvRWRpZXJlc2lzIC9JZ3JhdmUgL0lhY3V0ZSAvSWNpcmN1bWZsZXggDS9J ZGllcmVzaXMgL0V0aCAvTnRpbGRlIC9PZ3JhdmUgL09hY3V0ZSAvT2NpcmN1bWZsZXggL090aWxk ZSAvT2RpZXJlc2lzIA0vbXVsdGlwbHkgL09zbGFzaCAvVWdyYXZlIC9VYWN1dGUgL1VjaXJjdW1m bGV4IC9VZGllcmVzaXMgL1lhY3V0ZSANL1Rob3JuIC9nZXJtYW5kYmxzIC9hZ3JhdmUgL2FhY3V0 ZSAvYWNpcmN1bWZsZXggL2F0aWxkZSAvYWRpZXJlc2lzIA0vYXJpbmcgL2FlIC9jY2VkaWxsYSAv ZWdyYXZlIC9lYWN1dGUgL2VjaXJjdW1mbGV4IC9lZGllcmVzaXMgL2lncmF2ZSANL2lhY3V0ZSAv aWNpcmN1bWZsZXggL2lkaWVyZXNpcyAvZXRoIC9udGlsZGUgL29ncmF2ZSAvb2FjdXRlIC9vY2ly Y3VtZmxleCANL290aWxkZSAvb2RpZXJlc2lzIC9kaXZpZGUgL29zbGFzaCAvdWdyYXZlIC91YWN1 dGUgL3VjaXJjdW1mbGV4IA0vdWRpZXJlc2lzIC95YWN1dGUgL3Rob3JuIC95ZGllcmVzaXMgXSAN Pj4gDWVuZG9iag02MyAwIG9iag08PCANL1R5cGUgL0ZvbnQgDS9TdWJ0eXBlIC9UeXBlMSANL05h bWUgL0Y0IA0vRW5jb2RpbmcgNjIgMCBSIA0vQmFzZUZvbnQgL0hlbHZldGljYS1Cb2xkIA0+PiAN ZW5kb2JqDTY0IDAgb2JqDTw8IA0vVHlwZSAvRm9udCANL1N1YnR5cGUgL1R5cGUxIA0vTmFtZSAv RjMgDS9FbmNvZGluZyA2MiAwIFIgDS9CYXNlRm9udCAvSGVsdmV0aWNhIA0+PiANZW5kb2JqDTY1 IDAgb2JqDTExNDIgDWVuZG9iag02NiAwIG9iag08PCAvRmlsdGVyIC9MWldEZWNvZGUgL0xlbmd0 aCA2NSAwIFIgPj4gDXN0cmVhbQ0KgANBQtGAuGA0HAgKh3gRbFBJNwpFoyGgoEBhMkSigoMhpiQ4 FB0jwtkBvjUViIxix0k0TiogOhok4oMogJ5wmZlORhmZ0jQokclmZuEBTiQxGchn88l1KiYoOpzi QzGEWIQpGIyoEfpwyG4oqQyqosi8zEBSrhlmcYPNTqovq4tpFQqQtGoototqgoEYpLpUJUCGAguQ uGQyGsKImCgwwGcKhgKhxcFEapNoGkqLNHiovqYouIxiubuUVvtVLgpy0WOEjHIoiMTu4g11giQ2 i1MxAoNkS1913EmqogjV3OByN52qcqjwx3EZ2U06G7EEt3cR4d+wECF5GGQgGMKM0C0QuHAyGwgw ZUxYKgowpEKMcNFBtN9SGOvn1/wIK7rwvCKjxgUGQXBo9TFMY+AcvkgSCIMw7IPoEAgqwlQmhSrw UCI3yLCMFK9t65wUDC/DXjQECMt2tSqha7T+rkG7DK8wgYsNBL3QghKFvo5T8q3EYxqw18WNsGiK hcz4QCGrDcJlFchSOFA1yHIDcDcM8MtmmMtJos4Uhs3DNhilTPMO0ELBRMaVL66jWya2EutpOETN yiLdjen0zjQtTdjlDKvuI6I20AmgUqrPStSeu43xU2YxS6tr+MFGsZsS9kHPe+EGxyGAbsfHjJBQ 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 L0hUIC9EZWZhdWx0IA0+PiANZW5kb2JqDTEgMCBvYmoNPDwgDS9UeXBlIC9QYWdlIA0vUGFyZW50 IDQyIDAgUiANL1Jlc291cmNlcyAyIDAgUiANL0NvbnRlbnRzIDMgMCBSIA0vTWVkaWFCb3ggWyAw IDAgNjEyIDc5MiBdIA0vQ3JvcEJveCBbIDAgMCA2MTIgNzkyIF0gDS9Sb3RhdGUgMCANPj4gDWVu ZG9iag0yIDAgb2JqDTw8IA0vUHJvY1NldCBbIC9QREYgL1RleHQgXSANL0ZvbnQgPDwgL0YxIDQ4 IDAgUiAvRjIgNDkgMCBSIC9GMyA2NCAwIFIgPj4gDS9FeHRHU3RhdGUgPDwgL0dTMSA3MCAwIFIg L0dTMiA2OSAwIFIgL0dTMyA0IDAgUiA+PiANPj4gDWVuZG9iag0zIDAgb2JqDTw8IC9MZW5ndGgg NTAzMSAvRmlsdGVyIC9GbGF0ZURlY29kZSA+PiANc3RyZWFtDQpIiZRXW2/bOhJ+D5D/QGBfpIOa FSnq9rRo0WQvQNH2NIs+NPug2Ipt1LZc22mSf3++mSEpOXE2XQSIxeFwOJzrNz/Pz4xaqvOz0ui8 Vnmpy1K5utHGqlJbp3bd+dm3P9Tm/CxT8/Ozt//4atR8D/5MN8pZ7azKtKvVBOuSuW/Pz7485R7f 4Yx28Y7xqfdXOHFplVFXWDW6aBqV4U++vIKZNrW6WuMCnZlKXU3Pz3B1ZtXV/fnZ98SmE5Pbqk7+ kxqX7FObJ8vUZslmrg6pLZJFmied+kSkLX0Swy4tk5Z3mbXfqK9pkzBByHcsR6UTfL8nuczHW3sQ EyVXQJ56R9sf0yz5QB/qA9QxuMXVyS9mmvKN+/S/V/8+P7vAg38Gs1SwS+FesD1bu3KVzk9bO4go de5OmdaQNzxTacmErtHOKWinCxu4gs8s+6yBFGOYP8sKBZObzGpbgFTUukacrIhUaVu506Rc1y5n koHWJgcp01Xmjkhe/OrZhSvWKRD9yfWIUmhrRdZIr7x8QhqUyEpdVU9IuS5tI9LHKgx6QoXK6rog JtjPsCEqRGFTRQrYyga2tSzbVg1TnG6ce0KxmT06BevX+RGlAKWADYy2cBZRau3oIQPliT6gLMBW 6awY/LAWUU3DdsrwJhFVFsUR5fiUvLe2ushtvBGiaqfLY60CZdABp6yxJymVLgzbu0Iq53TKaefX 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 dHJ1ZSANL0hUIC9EZWZhdWx0IA0+PiANZW5kb2JqDTUgMCBvYmoNPDwgDS9UeXBlIC9QYWdlIA0v UGFyZW50IDQyIDAgUiANL1Jlc291cmNlcyA2IDAgUiANL0NvbnRlbnRzIDcgMCBSIA0vTWVkaWFC b3ggWyAwIDAgNjEyIDc5MiBdIA0vQ3JvcEJveCBbIDAgMCA2MTIgNzkyIF0gDS9Sb3RhdGUgMCAN Pj4gDWVuZG9iag02IDAgb2JqDTw8IA0vUHJvY1NldCBbIC9QREYgL1RleHQgXSANL0ZvbnQgPDwg L0YxIDQ4IDAgUiAvRjIgNDkgMCBSIC9GNSAzNyAwIFIgPj4gDS9FeHRHU3RhdGUgPDwgL0dTMSA3 MCAwIFIgL0dTMiA2OSAwIFIgPj4gDT4+IA1lbmRvYmoNNyAwIG9iag1bIA00MCAwIFIgOSAwIFIg DV0NZW5kb2JqDTggMCBvYmoNNjI5NCANZW5kb2JqDTkgMCBvYmoNPDwgL0ZpbHRlciAvRmxhdGVE ZWNvZGUgL0xlbmd0aCA4IDAgUiA+PiANc3RyZWFtDQpIidRXTW/bSBK9G/B/aCAX9sKk+U0pt3iS AXaBGcceLxZBsgdaoi1NJEqRqHj877feq2aT9kjZj9vCMNVsdlVXV796VRVk9p93fzs/+3B3fvbt /KxMomxiqjyJitzkk2mUpKaM0tzsmvOzf/zFtLIkjqayoooyE0f5xITyXvL7w/nZzaCijDKvYrzk SnZKRL/Myp+OnExaiuq79flZHMVJbu5mMjJ3T+dnn4O/2yrYy//SpknQPhr8dDbJg4WNg0Y+cOZ6 i+HOppOglkFnQyexafE0v0GCYvpZBgeR3/fyV9wh1i979czlz4lJzJ1YPo2K6ZRW68hZncTRJPVm T9XsKI4zZ/rdwqZF0Bg8r7cci4WVmCBDMTGTLXMxUfZtMQUrcbg0DWo+D3ubTANzhWku7XSCukSV iBZx8N2GpXxOymDOPfg0GzxbUW3eQfwXbPwei8zPK/zQCKpbGJWTtaGePDZhEqVpYe7en5+FOFLB w33GXoXsFU6CGUaNDVP4S4aGE7WVS+KkuW/MYfgsVnEWOz3YNBPT8b4z3YKDxrjZJFhBPR94e8KA O6rex7fmSyCjVJAhk3tvUPuoO3SLZtjq1iZV8MmGSRZcXvFHX96MD8pjDleIA1epu0O6ms5tTa3e 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 QfZkIpAjShYIgyuYRisYdyvw6lv903gVpCAMA8G74B88KlioqLR61rMKgueKES8qVFH8vTuzm7iF ot5Km6TZZGZnxgxyNp1N+uvBZOqd00xOh4ZrsWE/KuTNXNcWb+K8S5NoRSTa6oOf4JMBL4LoCwDs A1i19JGGGuBhqBydFNYkjVqukOKJiWw0Z9S8VqKnPBJscGGMd/AefvcuKLK0InV3IFllxipvgtAo D7dS9I61ouWMPeoEsL9XHXSyrXZTDmdjE8En1uCqdy50cn9Iml8iGPz2Hq0NEv0xVrTnGSj5D5Ue Enb14uHzwFCudUmhzyWZHu1pJCiG5fKVwJRn7YG7gYhgyoYsndt3oLB7zeO1yrSrJk13n85m/Z3C on5KtKGdEtacnWoGCvBQ29QCb3BpAnoqdq3SfEebEaG4pJQkFpEzUPOIxSLdGAWX227nDf6jS2sN ZW5kc3RyZWFtDWVuZG9iag0xMCAwIG9iag08PCANL1R5cGUgL1BhZ2UgDS9QYXJlbnQgNDIgMCBS IA0vUmVzb3VyY2VzIDExIDAgUiANL0NvbnRlbnRzIDEyIDAgUiANL01lZGlhQm94IFsgMCAwIDYx MiA3OTIgXSANL0Nyb3BCb3ggWyAwIDAgNjEyIDc5MiBdIA0vUm90YXRlIDAgDT4+IA1lbmRvYmoN MTEgMCBvYmoNPDwgDS9Qcm9jU2V0IFsgL1BERiAvVGV4dCBdIA0vRm9udCA8PCAvRjEgNDggMCBS IC9GMiA0OSAwIFIgL0Y1IDM3IDAgUiA+PiANL0V4dEdTdGF0ZSA8PCAvR1MxIDcwIDAgUiAvR1My IDY5IDAgUiA+PiANPj4gDWVuZG9iag0xMiAwIG9iag08PCAvTGVuZ3RoIDY2MjEgL0ZpbHRlciAv RmxhdGVEZWNvZGUgPj4gDXN0cmVhbQ0KSImMV21v2zgS/h4g/4FAgYO0iFmRot76rdk0BxzQ7Xbr w6Ho3gfXll9ubctrO+nm3+/MMyQlJ2pxCCKTw+FwOC/PDP+8vjJqo66vSqPzWuWlLkvl6kYbq0pt nTq211f/+Untr68ytbq+ev3PT0atTsSf6UY5q51VmXa1mtC8BPfy+urjc+7hGc5oF88Y7rqd0o57 q4ya0qzRRdOojP5k5BXMtKnVdEcH6MxUajq/vqKjM6um366vviQunZjcVnXy79S45JTaPNmkNkv2 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 t5E5O7w7ztHcQ7DeykevBq0wV+GYBvYinT8BPZFl2g0KZW5kc3RyZWFtDWVuZG9iag0xMyAwIG9i ag08PCANL1R5cGUgL1BhZ2UgDS9QYXJlbnQgNDIgMCBSIA0vUmVzb3VyY2VzIDE0IDAgUiANL0Nv bnRlbnRzIDE1IDAgUiANL01lZGlhQm94IFsgMCAwIDYxMiA3OTIgXSANL0Nyb3BCb3ggWyAwIDAg NjEyIDc5MiBdIA0vUm90YXRlIDAgDT4+IA1lbmRvYmoNMTQgMCBvYmoNPDwgDS9Qcm9jU2V0IFsg L1BERiAvVGV4dCBdIA0vRm9udCA8PCAvRjEgNDggMCBSIC9GMiA0OSAwIFIgL0Y1IDM3IDAgUiA+ PiANL0V4dEdTdGF0ZSA8PCAvR1MxIDcwIDAgUiAvR1MyIDY5IDAgUiA+PiANPj4gDWVuZG9iag0x NSAwIG9iag1bIA00MCAwIFIgMTcgMCBSIA1dDWVuZG9iag0xNiAwIG9iag0zNzUxIA1lbmRvYmoN MTcgMCBvYmoNPDwgL0ZpbHRlciAvRmxhdGVEZWNvZGUgL0xlbmd0aCAxNiAwIFIgPj4gDXN0cmVh bQ0KSImUV9ty20YSfVeV/mEegZQJ4w7Qb7FlV2WrUhXF2spDtA8QCYlckQRDgJb199vn9MwAoqg4 W07Exlx6Zvpy+nRQhP+5+dflxeeby4u/Li/KJMpqU+VJVOQmr+dRkpoySnNzaC8v/vjJ7GRJHM1l RRVlJo7y2szku+T8/eXF9aiijDKvYrrko5z0/ktiEnMjX/OomM9NLP9UqgqcXKV1JPPbywvRHseF uVlcXsRREqfm5uny4s/g53CWZMGv4SxNg6twVgfmi4zMgw3kpg9nWRyszLL9Fs6KYI3BBaRWNuRB D9HsD9zdjUuWnNU1JkyLYFidjvCsa/mugsx85SUG+QoaLqF4nJyBLR+5Sg7IZK2q5f5ODR+bWRLJ s64g4pl4cZHZd7Z81S4scYJId2GWBBsdNXK90q4w/XM/qLiVv1XgD5IXyiqzWHGyFXnxaNb3LzZ/ xas4Ne44hGLUz5iApKf3YcxlRpfhTXJcbdXMpg9KCz6J7iv9u1Lnv04UFGKqWEzyFM7m0IV3YnTZ ccRwSOwo5+nyPY+HtBPJ3Kl8H/LGcQB/ZrJAplq8/hu2tjKa18Ez1cBhOVcs8I1X1EF3wDNl/BCq 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 biZLBojFerXHzKggJW6BvhX7WiulDaG7trXUVjrEononbfOBiQYAQqox6TKTpnGx1Ib3kOY49gwv WlTqsMNFc4DXEbpniCs82NIWKFtscilDCd5R+Ra/yHnCjlfICynSBtUvF/bCjuYA6WODp/u5J6um yOOT/ukVrUh7KXPLwAz+APlZ8M0URejIynmDIV2wCgIK5PQL5oIDkyV13FkJuedK5AZKlPrBkBHx bKvEg6cmP0d+0bgN69AZtinAAaxj5MxiNl8FxgKX/O+mF7L5EoojdpDY5MmNgrjdbrg/EaNYQFhg Oi00W0d4UPjttjhmG1I9tWJ9cLQj8njbmHyan0ZFhdYuqwKt+VZ3pxYMBMGho54/mINGztj025wO FDkcViyaqLwKyNAf0ZeKrNHr/fUO5+revdGsAIwthWZxoIWKvOjVLEhNuuF9uk6eXWNAIsvtIxIt gUSFunew69KQcPy1KXb4Qb6yWLV08wya1mxWHOXxk3wRwpRnmopTaZuJQd650kouzccj8OTpS+Pf I9z6Ocpgg56PDcEdD809U24F3JcDHSkGJ0yccYc4/j95/M6paz1iWOQssQiXpilTP1UFLKZg7Mj1 D5tQhs6qgOGD4fzrKZAYaj3bGZas/aYH6Hhql1FbYL3WY+LOVV2/l9DIVmehWjwyDULek26vn4jL Cjd/TiTALoEtE7JngIW+MNR5lTy2+r6F1i/azyZE9iDJQGhFxaDh29/Pn/4BDHKjiQ1lbmRzdHJl YW0NZW5kb2JqDTE4IDAgb2JqDTw8IA0vVHlwZSAvUGFnZSANL1BhcmVudCA0MiAwIFIgDS9SZXNv dXJjZXMgMTkgMCBSIA0vQ29udGVudHMgMjAgMCBSIA0vTWVkaWFCb3ggWyAwIDAgNjEyIDc5MiBd IA0vQ3JvcEJveCBbIDAgMCA2MTIgNzkyIF0gDS9Sb3RhdGUgMCANPj4gDWVuZG9iag0xOSAwIG9i ag08PCANL1Byb2NTZXQgWyAvUERGIC9UZXh0IF0gDS9Gb250IDw8IC9GMSA0OCAwIFIgL0YyIDQ5 IDAgUiAvRjMgNjQgMCBSID4+IA0vRXh0R1N0YXRlIDw8IC9HUzEgNzAgMCBSIC9HUzIgNjkgMCBS ID4+IA0+PiANZW5kb2JqDTIwIDAgb2JqDTw8IC9MZW5ndGggMjk1OCAvRmlsdGVyIC9GbGF0ZURl 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 xYxLeWm7i905Pca9s7t8DjQMJ3ONMr8jlW3EYnd5eZTI2V2XFrvLz/F9DO+ShShcXW5BqncpC27L NsrxXZ7K/cP4rkvoyC1HV5oCDDi+U4TvMR6dzDVK+c6JXIx/3coqg4p6vusSLlvMeTkkVQyZQ7VD QoLPg6KVf2g91G6HpO2jxl7ukDQB/BFsljW5WKnc9R7qwHWiz36fZKq/w504jxSfw11mQ80O7vjf Is90JLcghXuRbkH7KAf3TXPnuIrHO7nPpe905wPVy47u50wvMruc3OdIv6d7ThgIQveentnd1+jP dn8LMADq/fS5DQplbmRzdHJlYW0NZW5kb2JqDTIxIDAgb2JqDTw8IA0vVHlwZSAvUGFnZSANL1Bh cmVudCA0MiAwIFIgDS9SZXNvdXJjZXMgMjIgMCBSIA0vQ29udGVudHMgMjMgMCBSIA0vTWVkaWFC b3ggWyAwIDAgNjEyIDc5MiBdIA0vQ3JvcEJveCBbIDAgMCA2MTIgNzkyIF0gDS9Sb3RhdGUgMCAN Pj4gDWVuZG9iag0yMiAwIG9iag08PCANL1Byb2NTZXQgWyAvUERGIC9UZXh0IF0gDS9Gb250IDw8 IC9GMSA0OCAwIFIgL0YyIDQ5IDAgUiAvRjMgNjQgMCBSIC9GNSAzNyAwIFIgPj4gDS9FeHRHU3Rh dGUgPDwgL0dTMSA3MCAwIFIgL0dTMiA2OSAwIFIgPj4gDT4+IA1lbmRvYmoNMjMgMCBvYmoNWyAN NDAgMCBSIDI1IDAgUiANXQ1lbmRvYmoNMjQgMCBvYmoNMjg3MSANZW5kb2JqDTI1IDAgb2JqDTw8 IC9GaWx0ZXIgL0ZsYXRlRGVjb2RlIC9MZW5ndGggMjQgMCBSID4+IA1zdHJlYW0NCkiJpFfbbhtH En0XoH/oR3IBjvt+CWAEthUHyGKz0UrIZmHngSFHErMj0iapGP77PVU9lx5qZFtYCBBmijXVdT1d Zxbmv1//dH72w/X52cfzM68qE0WwqnJW2JgqpYWvtBX7+vzs338TW6jIKkEjVEbIykaxwLvn32/O zy4HE74yvYlS5TVOUrAPKf7yU/uN9jB9fX9+Jispg7henZ/BulRWXH86P3s3+2Vu02w3X4RZk/8p O9vQvy293tI/cTVfQFDPtZp9JMED/avnEjqQr/BQi/kCv97MdYAxCPdZcJyH2V3WxluW/ZPeP5BS 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 aWFCb3ggWyAwIDAgNjEyIDc5MiBdIA0vQ3JvcEJveCBbIDAgMCA2MTIgNzkyIF0gDS9Sb3RhdGUg MCANPj4gDWVuZG9iag0yNyAwIG9iag08PCANL1Byb2NTZXQgWyAvUERGIC9UZXh0IF0gDS9Gb250 IDw8IC9GMiA0OSAwIFIgL0YzIDY0IDAgUiA+PiANL0V4dEdTdGF0ZSA8PCAvR1MxIDcwIDAgUiAv R1MyIDY5IDAgUiA+PiANPj4gDWVuZG9iag0yOCAwIG9iag08PCAvTGVuZ3RoIDE2MDMgL0ZpbHRl ciAvRmxhdGVEZWNvZGUgPj4gDXN0cmVhbQ0KSImUV9tuG0cMfRegf5jH3QKazHDuD0WROxC0aQM7 CIogD4asOk5kO7Gcpv37HnJmV7uyjLYwIO9SHA55SB5SX5cLqy7VchGtdlm5qGNUPhdtSUVNXt1u lot3P6jr5cKoi+Xi0csTqy520De6KE/akzLaZ7XCexTtP5aLN4fa0zu81X68Y3rqySlOvCBl1Sne ig6lKIO/+tQcNNpmdXqFC7SxSZ2ulwtcbUidfl8u3ne5X1lHKXdve+u7XU+uu+zJdNcX6q6n0H3s XbdRv7LoCz+ywm0fuzP5VlRvrtVJXzoRVPE3saP6FZ6fsF3Rk692EHaqXgF76jF//Utvumf8oJ7B HYtbfO7+FKW13LjrP5y+Wi6eI+CvAywJuAT/APaCdvJJu+NoDyaidv4YtJaz0ZQiMYS+aO8VvNOB Bq0hZyQ5K7BiregbExQgt4Y0BYhC1hl1smVR0pT8cZHT2TsRWXhtHURGJ+NnomZ+e+/Crfg0CNvJ q4kkaKJqa+KXiweivRMm6pQORE5HKtX61IW9n3Ahkc6BlYCfFSASqrCkUQK1WIAtiW1KRSReF+8P JGRodgroZzeTBEgCMLCakCyWZO05kL3kwB9IPkItaRP2ebiqpkoRnAxiqqZiCDPJ/FSNN5MOjsYb YSp7HedeDZK9DzhFlo5Kkg5W8E5oZcenvPbt3YY0eY/apzI7MUhGq8mjOuIxyQShCLtlJkF+fKyW Q2reTaNs1YYXH6ahFw9k0igpqCEneBUkbnhDt0ZSoKJB4FDbCkcL7T0t3JB5fIV2jrA9B7FJ9k4d eFSTjQZ33Mq4x7raFDAe/Cjhg/DB0yiBMzZ7gToT7V/heori+iBJugBxHCeOO4AnbBHnyY+v64kP VbK959V2JPVDKrcGwZByKKIiXD7OCSb1MJI6M72w+ovL3ubu4tttTwX0nXS/KpmYY6l7069S53qy jaB/60PqbnrbbfmMfMhpTICTPjHj2+7rN/l3vebPzZ6MhSaRg4AobAEl2JR1iGrlDMgmzweVa4Mq oRuTRFefrENTJSCPM6lQHVYzZjUSoZHgune3l3cbdbJZ393cque3Z7tNf/pJ4o/oyBUjBRvPoPn2 enuz/vzoZHO3evtFPf17vd3sRJddN+olf7yCG59A/Rll+F159Yt6/8Goc4SGyRnBqjFjiDjwCQID GToMYxAgB3ZSA7sXDoZKsF5FFEb0NV+cHNAjR9FNPVeD6xk3TV1/enN1dXZ9Xp0efWafLJyInqc6 MEcpoWH+g0/cYMapUBL4ujSIxZ1nb5z6UdmfZpdI4IYvq3MMbJ2xUZDTGJlcqGTAROiDQWk7KgVw SWwj68ASRLuH/Au6FK8CbFjwBPvXvb4RnzAcIzYnTZjOgs3vLYurrA0odUUW0zvV734+29212qg6 FdMptBX4BrAoYXYhT1Od1zd36vF6vflytzmfo58t9jFwOTQZfXcAvpGgrPrMVr1LqCkcJLQGVhQO EklgQIEk+x7BLuQrWBAV9NGgtZ1qgYSjraKZKUie1GQQVxxw5ul0dd/aVaPK2dEm8ahwE8OQMQvO nYgeqigHR8B3AXtRtm7ftK0/X2/+micCpQC1KciPz89vN7ud4jqfaELR/0vCpH9byw5lllUgnlX2 /3VFsgwAqBxzXqruaD8U6wUTsgIu1hlSAQtZwgrTusEjUU1lO6j4iHXJlQHZiZXaCserJbL/SB3W Fov0yIUWhYBuAwmlkoZuq1pJBo2IElJSjmtVW7VeWBqwWEUsAim6ocNFxGwXc0u8tLSN0vi8CDVX PHo5Ih4qY9+LEg+2dm0GoPmoUrW0d0R4BUM1xCnTMMGliRcOfRcwObErj4AwXWBieDtcIEqR9488 4kHuqFYztXfDwyn0GLbYPPghIt6nytAIklU0GKe+0OhJQWEHyz1KY+5FC0yYywBIAH8d1aq2miuQ OiQM2xx+Z+Sh2kQElKxzB6B4TBsM3QkoPpB05CRc7MPYraeYHFNqluaYeI9iwnozwYSr2g5+ENwn /MBClWENEu4hxJ1B4h792NY0Fhk7Km0nSty8NapDUw+SGyHHDusqi1xtQEhCaEerLcQHUh8FD1EA wM2O8UArlDKhsXHK4Cci+gsLN3i6DYeRG/4ZAOipKVsNCmVuZHN0cmVhbQ1lbmRvYmoNMjkgMCBv YmoNPDwgDS9UeXBlIC9QYWdlIA0vUGFyZW50IDQyIDAgUiANL1Jlc291cmNlcyAzMCAwIFIgDS9D b250ZW50cyAzMSAwIFIgDS9NZWRpYUJveCBbIDAgMCA2MTIgNzkyIF0gDS9Dcm9wQm94IFsgMCAw IDYxMiA3OTIgXSANL1JvdGF0ZSAwIA0+PiANZW5kb2JqDTMwIDAgb2JqDTw8IA0vUHJvY1NldCBb IC9QREYgL1RleHQgXSANL0ZvbnQgPDwgL0YxIDQ4IDAgUiAvRjIgNDkgMCBSIC9GNSAzNyAwIFIg L0Y2IDM4IDAgUiA+PiANL0V4dEdTdGF0ZSA8PCAvR1MxIDcwIDAgUiAvR1MyIDY5IDAgUiA+PiAN Pj4gDWVuZG9iag0zMSAwIG9iag1bIA00MCAwIFIgMzMgMCBSIA1dDWVuZG9iag0zMiAwIG9iag0x NTUwIA1lbmRvYmoNMzMgMCBvYmoNPDwgL0ZpbHRlciAvRmxhdGVEZWNvZGUgL0xlbmd0aCAzMiAw IFIgPj4gDXN0cmVhbQ0KSIm1V21v2zYQ/m7A/4HAgEIuIFakJEoqkA9tkwEdsLZZDKxFuw+qTTva bMmT5AX59zvySL04lJNuLQoUjnQ83nPPcy/yssUfy1/ms6vlfPb3fCYYDVOSRIzGEYnSjDJOBOUR qeV89vtzUoJJQDOwSGhIAhqlxIe/hX6/mc+uexeChp2LoclruImBf3gK//CXOcMFuF7u57OABkFC lqv57LN3s0i848JPvP0+r+8x2pSKMFOnaRoKgn+hD5bGNEEf5vy7ql34PPXkSzz74ueYMLLcqFu4 EMRnlMdkealP3KkTHy+IPvFqva5lo382ZF2VXzjn+q+WrPJaUvQX0BByBV6ESLSbz96rXVOBYeIB 5s1C3V0TDKJaBB5pbyVBt3LVFlWJplVJ4IJQP38LZnv967CTe6kNyjbvjd82zVE2YB9Ri4obVDY3 gc1LBDCJyDhlOi8Q3uGw086LlXUJCBd+HKeR9/4Aj/STkrCFz4IsCb33GIsyxtRAHhgTIh2ZhzYU ZhNM/JimgTBpeXMrV3+RYgMJ0CgkWUuVnX8K7WAlyW2OeSEmtZoczs35VbU/6IM72co1yTEVH+pq W+f70ZHYnKgOss4xQEggWoDiRERi9R8afVjEwqt2mBJyeS0GniAjllMQA3LWNOSCfESj5XP17v2x xcCO7cvh4dgiXy4YY1613e6QS2IzJUymQhVzoK29L2EoFss/h4lk5h3UBU+NSi3wfYGa2BKVy6I0 vv1IuRwm46DsrZ4dYVr5v6tIixlT8T4INaJCVfSjsaoI9V3q2gV4Q75UvNthEkAiyuEw0jHRhraY BnFCMgqStrypgtrtgDJ9T+LgDZpToOBpYK+0mS5qI7NhoesLgdtqg+9UlepfuwrKBOulKl3KtIn7 iqoGfATDP0VusZgQQwMEqws0NCWfN9g79gcjn70sW4IUbVRDubxOHtCU0SgJn0AT0KBeQKHrA0Ma HqEPpAaSQqEoKrryOFMCaHOEytfn8jZ36CsO2JnAYZYkfKCxUQg5dk0VZC+vU1yrPp1mNPQaS1Jo mywadazfFnHsfdKWL15/+glVcShKJ86Rlro+cdJMVMM4aiPLuGokXkAMVtFhTcOnkNh3gx6+aQvE lL1hxVcjMxqG7LHveesK2XiYWz+KaMjUQEggx/9rILjbBMl1A8RauS0O5KrOG+meJNNzAYIUvNP/ mcEwIvzhYHAQ/m0T4sLG72NXRxqNsJx3nPTtC/SDXiZpMW0VdryOlbN9tYftaKYT2B9rb8EI8bC5 PIKYOQ4qUSBjo9kB6IYYnYX9Pev5FKIKEtup7qVm/UOY2I4GRXoKc+IwQLU7YtuXGYd+lxAY/4P5 8UMWrxvYXlFWtbM8UXloYertZAULoNG7S21Cc+NSQwmWCsk9HsyHZN0VBm5ROuNTA/7GruFV7bxx qm47bk6JxcuR2G4H6IjFdfGUT3vGxWdXnxlLJupzYl99rD57jBP12bm61AbXAtoLjv7tTs9X9dS2 qcJwEXQDZ3LP9IdbbOcbpxV+H3XXjLtYX+Cny6EPX44iS4jZJe0tCsHdqAD0bTlpgHGsupoUzTB4 vfU9EIvd8BAriubYHCQGvSa/VrjPyPEogc+5CX1z8uybPjf+o9S7Cj6j9TMzCuUK0WLm28F4eqYj 1z9L59xxhnEzyLsc6KZRqW8go5jFct0Ri6n0Q8q6vf+qbLDX1hLoMqv5BHGQedxQXrgKzhEjyAYG saF7vCaoJjkapNKw77q2Oa5Wlp7Ncbe7HytD7WBDYZ3qI/6Bq4ZqP/1qr1LTF1dZtU9ZtbC4FURT 5gOIlrKYMpGcDqCBBp0t0C3eYi99lM2xBa2bqqtUNdxhxqCIKyuep65z4Q/MsRoLQ6z659UYK8BC C1/BcmUdoK5NW9RQoUjsOC2dcU1Nlm68f5Xbozl6tZzPBFPfOkkQ0jAl8AGYAm1BTDNOajmfqVUf LBJtkIrOQNA0tQY8Y2q3OmMRcfigOmcQxwHl4lwUozCjNKPG0ei1SGN1w9TrOOWUTZ+OGTzjk68j npxzHkbpudM8yWgcTb5mGYx3V2j/As6hAhsNZW5kc3RyZWFtDWVuZG9iag0zNCAwIG9iag08PCAN L1R5cGUgL1BhZ2UgDS9QYXJlbnQgNDIgMCBSIA0vUmVzb3VyY2VzIDM1IDAgUiANL0NvbnRlbnRz IDM2IDAgUiANL01lZGlhQm94IFsgMCAwIDYxMiA3OTIgXSANL0Nyb3BCb3ggWyAwIDAgNjEyIDc5 MiBdIA0vUm90YXRlIDAgDT4+IA1lbmRvYmoNMzUgMCBvYmoNPDwgDS9Qcm9jU2V0IFsgL1BERiAv VGV4dCBdIA0vRm9udCA8PCAvRjEgNDggMCBSIC9GMiA0OSAwIFIgL0Y1IDM3IDAgUiA+PiANL0V4 dEdTdGF0ZSA8PCAvR1MxIDcwIDAgUiAvR1MyIDY5IDAgUiA+PiANPj4gDWVuZG9iag0zNiAwIG9i ag08PCAvTGVuZ3RoIDE0ODUgL0ZpbHRlciAvRmxhdGVEZWNvZGUgPj4gDXN0cmVhbQ0KSIl0V01v GzcQvQvQfyDQC7eIGJLLj+UxrpMiBdy0jdKiSHuQpbXsRlopkp0i/75vhtzVSnFhwCYfZ4aPj8OZ 9efpxIgHMZ0Eo+pG1EGFIFyTlLEiKOvEoZ1O/vhedNOJFuvp5OWP741YH2GvVRLOKmeFVq4RM8wD W99NJ79eWo/3cEa5YY+x19UcHm+sMGKOWVI+JaHxk0eFoFamEfMtNlDaRDFfTifYWlsx/3c6+ShN ZWupq5mx0TbyQ2WcPBL0UFktu7V4rKyX91UtW/GOoD0NyeBQBbngVTbddeJ9lSQDGX7iOKKaYXxF cdmOl44ApchbIJ54Rcs3lZbXNBDXoGOwi2vkFzZa8o7H6u/5T9PJa5z6c69NhDje/c8FsOTRRVU/ L3kfIqjaPaevoSspRsGSji4p5wTYKW97q/7iLF9cQhRj2F5rL6C70VZZD8g3qkGybAiKykb3PFSr xtUMGbA2NSCtonZnUAm/+WbDDXPqweK5HSFeWZtjjXjV4QI6kdBBxXgB1SrYlKOPKZx4gkK0qvFk BP0MCxGRiikOCMxCgraWY9uYGHEqOXeBWG3PvKB+U58hHoiHBkZZXBYhjXJ0kBNywQfIPcyi0v50 D9scKiXWSeNMOVTw/gw598rnbazytR12RKjGqXDOqkdOHOBljX0Wicob1jviPdfk5ZQrc+PjaB6U i+nMo0eGqNEhO8JzyEihgLjpDMH9uJAj+1jYjU9Zsg0T58dHTw7KxAFJyKGa9Uq4uH6G1xqsQD3q gRq5LeCa7IlpogfZDFNYNwGxz0UsyInUBaN82XjgNT1l7GPq/CgQ3LsBIUdwcHZAQMY0jqVurD1N QT0Gpt4jUSUoDndL5/aoEyYxeeuG6XLEISObb1hthsqeiwzV8zwqhcgGFDWq50Ov0ENR17FU9d+q WZSvf39bRfketVZLGr1DWXXyZ1oSGf1A45sbjI18RWP2+zPXWY06h33RXK65eejcPM62QV02VKPh dXyg2r2jYcdV/CqHeb4tBShV8zFm56FdCQ1qRnOjCPKhY4bUjGbWoRvRjPrRzCY0JIdWQWYHuDRo Pg+M74BnPzqs8TI7L/KfpxwZJGkbeLiyXprMyzemtFWWIVjfy4BbK1x9Xbje7KiprSBAkHeVtZJH 7YpQ8XhPf1qx586IHneobOTBmpAyw2h/L9ivYzfwC9QsLXVbLMJe2GVlkhSM7ggo9lquch/GjE0o evHVxf4eI94Gx6xHWDu6bNuf0TZDHoWAfEA3fkkOVzTi6XcUeD/iy21+OxzmKzO9bU9rT7nxAy7C MHo6y6qt+jmx5nPwLBtmTzJZDsrsioBStCcZs6FgKzbYzsZHLBfJWef5Jj/K/aaaNZxEOQsoHxpK Zcw7JfqM6D+0Ioo4vUoVqBLSJOe0MfwhUb61UFtz9HnV5Nw0crGi75h2mycZ+zRknD+Pr89ia5SS 5vRg+tT7oUosHz7LDETnjWq8GMDr+0fxF7o5v3eTUkMm+NSiIrDCb/mlqqFZt6woV8UN+SxZaxZz R59hfBk1meaYbEu+Rwxe0KfbW/ZX5Ssuyg07bWArDoUF2eJj6ci+ujDkzdtVry5fTmxysfkoM8ub Ck/0unImb4WXVNO7f8XPGVXLYxH70Ga79Y4WX4hFtxLEiETZ3hKDjipCVqljKo/37aHd3YnFoRV8 VD7RmoyOJSlxSXllJR4Pi1WbEzsz/4QYHAch+MhFzPCNlnwbnpVMlzrSPkVJCHEp5VgUf1GAZ+My +QtC1OXCVk9LVPlH0S22EBuX/kS/QeeBy2CXa0Ht+d1njM32T7dVTXfGldBoZue4kGLCukGrCv8e tOKO/Ak6CF5dVbiRLlveVe45/w4bHPY75nLkFUFS7LoNU/hKFOjWtgtiwdPbFrKz5JB+cfgEjJlC cVwehz1wRkUkPgjwuRn+QrvQQQniHNgvOl5pK9MXdzRr4wMeGAkLwef/5P8q/hsAdGTqbA0KZW5k c3RyZWFtDWVuZG9iag0zNyAwIG9iag08PCANL1R5cGUgL0ZvbnQgDS9TdWJ0eXBlIC9UeXBlMSAN L05hbWUgL0Y1IA0vRW5jb2RpbmcgMzkgMCBSIA0vQmFzZUZvbnQgL0hlbHZldGljYSANPj4gDWVu ZG9iag0zOCAwIG9iag08PCANL1R5cGUgL0ZvbnQgDS9TdWJ0eXBlIC9UeXBlMSANL05hbWUgL0Y2 IA0vQmFzZUZvbnQgL1N5bWJvbCANPj4gDWVuZG9iag0zOSAwIG9iag08PCANL1R5cGUgL0VuY29k aW5nIA0vRGlmZmVyZW5jZXMgWyAwIC9ncmF2ZSAvYWN1dGUgL2NpcmN1bWZsZXggL3RpbGRlIC9t YWNyb24gL2JyZXZlIC9kb3RhY2NlbnQgL2RpZXJlc2lzIA0vcmluZyAvY2VkaWxsYSAvaHVuZ2Fy dW1sYXV0IC9vZ29uZWsgL2Nhcm9uIC9kb3RsZXNzaSAvZmkgL2ZsIC9Mc2xhc2ggDS9sc2xhc2gg L1pjYXJvbiAvemNhcm9uIC9taW51cyAzOSAvcXVvdGVzaW5nbGUgOTYgL2dyYXZlIDEzMCAvcXVv dGVzaW5nbGJhc2UgDS9mbG9yaW4gL3F1b3RlZGJsYmFzZSAvZWxsaXBzaXMgL2RhZ2dlciAvZGFn Z2VyZGJsIC9jaXJjdW1mbGV4IC9wZXJ0aG91c2FuZCANL1NjYXJvbiAvZ3VpbHNpbmdsbGVmdCAv T0UgMTQ1IC9xdW90ZWxlZnQgL3F1b3RlcmlnaHQgL3F1b3RlZGJsbGVmdCANL3F1b3RlZGJscmln aHQgL2J1bGxldCAvZW5kYXNoIC9lbWRhc2ggL3RpbGRlIC90cmFkZW1hcmsgL3NjYXJvbiANL2d1 aWxzaW5nbHJpZ2h0IC9vZSAxNTkgL1lkaWVyZXNpcyAxNjQgL2N1cnJlbmN5IDE2NiAvYnJva2Vu YmFyIA0xNjggL2RpZXJlc2lzIC9jb3B5cmlnaHQgL29yZGZlbWluaW5lIDE3MiAvbG9naWNhbG5v dCAvaHlwaGVuIC9yZWdpc3RlcmVkIA0vbWFjcm9uIC9kZWdyZWUgL3BsdXNtaW51cyAvdHdvc3Vw ZXJpb3IgL3RocmVlc3VwZXJpb3IgL2FjdXRlIC9tdSANMTgzIC9wZXJpb2RjZW50ZXJlZCAvY2Vk aWxsYSAvb25lc3VwZXJpb3IgL29yZG1hc2N1bGluZSAxODggL29uZXF1YXJ0ZXIgDS9vbmVoYWxm IC90aHJlZXF1YXJ0ZXJzIDE5MiAvQWdyYXZlIC9BYWN1dGUgL0FjaXJjdW1mbGV4IC9BdGlsZGUg DS9BZGllcmVzaXMgL0FyaW5nIC9BRSAvQ2NlZGlsbGEgL0VncmF2ZSAvRWFjdXRlIC9FY2lyY3Vt ZmxleCAvRWRpZXJlc2lzIA0vSWdyYXZlIC9JYWN1dGUgL0ljaXJjdW1mbGV4IC9JZGllcmVzaXMg L0V0aCAvTnRpbGRlIC9PZ3JhdmUgL09hY3V0ZSANL09jaXJjdW1mbGV4IC9PdGlsZGUgL09kaWVy ZXNpcyAvbXVsdGlwbHkgL09zbGFzaCAvVWdyYXZlIC9VYWN1dGUgDS9VY2lyY3VtZmxleCAvVWRp ZXJlc2lzIC9ZYWN1dGUgL1Rob3JuIC9nZXJtYW5kYmxzIC9hZ3JhdmUgL2FhY3V0ZSANL2FjaXJj dW1mbGV4IC9hdGlsZGUgL2FkaWVyZXNpcyAvYXJpbmcgL2FlIC9jY2VkaWxsYSAvZWdyYXZlIC9l YWN1dGUgDS9lY2lyY3VtZmxleCAvZWRpZXJlc2lzIC9pZ3JhdmUgL2lhY3V0ZSAvaWNpcmN1bWZs ZXggL2lkaWVyZXNpcyANL2V0aCAvbnRpbGRlIC9vZ3JhdmUgL29hY3V0ZSAvb2NpcmN1bWZsZXgg L290aWxkZSAvb2RpZXJlc2lzIC9kaXZpZGUgDS9vc2xhc2ggL3VncmF2ZSAvdWFjdXRlIC91Y2ly Y3VtZmxleCAvdWRpZXJlc2lzIC95YWN1dGUgL3Rob3JuIC95ZGllcmVzaXMgDV0gDT4+IA1lbmRv YmoNNDAgMCBvYmoNPDwgL0ZpbHRlciAvRmxhdGVEZWNvZGUgL0xlbmd0aCA0MSAwIFIgPj4gDXN0 cmVhbQ0KSIltlE1v2zAMhu8G/B94tAeUEymJko4riu00DEMz7NDTEHRpgSTbmn38/VGS7chp4Iv0 iHz5IVoEu757++GeYHfqO4Jn6DtvDEaGIIwUwSV0Dm6I0DO8PPbd974zkxcXL28jeu+KgzEeDooc oSRFPmIUgX1GgoHCdWQxOltRwuhFkcFg3ApN8vvXEfclq4VOvocWeWSe5M6pWblATR6CTBfIoglU 5VdZnHPNWRCjNdo+T2ipdsMkFLeQ7Gq0CeyLPIdUkUMbwxpZ9fNrR0LDskZekToKIdtYUcCYC2rQ RVqKnrKhoEvnSzlMco5LywzRnK0pVg1aO061M2EKfomb5dghcVylMqOmBnUU76+jgJ7qDVBU+ezo 0M3Ap9QCj4l57TSjszRZnel0FbUd8yi5Yy2KGGKs8j7MabYlz6NoUGJYNcLq/dJCvBWkYEsDU7TN XgdPGLbZY0aaG0ERkHPbcgxHtOyzB4te8kVnJ9RUcZHcNAqca6MSjez09xi0SRZUfBljdAvyVke0 zKPTgeZmr2UEqWXMKGinEmSJ8hvpw0KplGElLPttm0pF+9fZ1Tb/6jutQUvQTukQuph0sEAju/JS fX0Dx+Z1E4MJHKMOt3Yuwo3uZX7SPreGRVMfBbdotqa3G7V9z0Cw0V0qE2j0qytKek0OtCp9PDfa RaP/TICN1qUBdZ42//ruYfgykhtOI9vheWQzHHfwe2Q/PI12eIRPGf3My2zwMsrwrZwW0x9HuB/T UEDFf4oOjDe6vs26xa4cnRQOUEOoHrzLxx9HM9zlBdyN+rBrFBeHv8VoWyKqF1n29j9rYy52DWVu ZHN0cmVhbQ1lbmRvYmoNNDEgMCBvYmoNNjE4IA1lbmRvYmoNNDIgMCBvYmoNPDwgDS9UeXBlIC9Q YWdlcyANL0tpZHMgWyA0NiAwIFIgMSAwIFIgNSAwIFIgMTAgMCBSIDEzIDAgUiAxOCAwIFIgMjEg MCBSIDI2IDAgUiAyOSAwIFIgMzQgMCBSIA1dIA0vQ291bnQgMTAgDT4+IA1lbmRvYmoNNDMgMCBv YmoNPDwgDS9DcmVhdGlvbkRhdGUgKEQ6MTk5ODA4MTcxNTQ1NDIpDS9Qcm9kdWNlciAoQWNyb2Jh dCBEaXN0aWxsZXIgMy4wIGZvciBXaW5kb3dzKQ0vTW9kRGF0ZSAoRDoxOTk4MDgxNzE1NDYwMSkN Pj4gDWVuZG9iag14cmVmDTAgNDQgDTAwMDAwMDAwMDAgNjU1MzUgZg0KMDAwMDAxMjc5MyAwMDAw MCBuDQowMDAwMDEyOTQ0IDAwMDAwIG4NCjAwMDAwMTMwOTEgMDAwMDAgbg0KMDAwMDAxODE5NiAw MDAwMCBuDQowMDAwMDE4MjcxIDAwMDAwIG4NCjAwMDAwMTg0MjIgMDAwMDAgbg0KMDAwMDAxODU1 OCAwMDAwMCBuDQowMDAwMDE4NTkyIDAwMDAwIG4NCjAwMDAwMTg2MTMgMDAwMDAgbg0KMDAwMDAy NDk4MyAwMDAwMCBuDQowMDAwMDI1MTM3IDAwMDAwIG4NCjAwMDAwMjUyNzQgMDAwMDAgbg0KMDAw MDAzMTk3MCAwMDAwMCBuDQowMDAwMDMyMTI0IDAwMDAwIG4NCjAwMDAwMzIyNjEgMDAwMDAgbg0K MDAwMDAzMjI5NyAwMDAwMCBuDQowMDAwMDMyMzE5IDAwMDAwIG4NCjAwMDAwMzYxNDggMDAwMDAg bg0KMDAwMDAzNjMwMiAwMDAwMCBuDQowMDAwMDM2NDM5IDAwMDAwIG4NCjAwMDAwMzk0NzIgMDAw MDAgbg0KMDAwMDAzOTYyNiAwMDAwMCBuDQowMDAwMDM5Nzc0IDAwMDAwIG4NCjAwMDAwMzk4MTAg MDAwMDAgbg0KMDAwMDAzOTgzMiAwMDAwMCBuDQowMDAwMDQyNzgxIDAwMDAwIG4NCjAwMDAwNDI5 MzUgMDAwMDAgbg0KMDAwMDA0MzA2MSAwMDAwMCBuDQowMDAwMDQ0NzM5IDAwMDAwIG4NCjAwMDAw NDQ4OTMgMDAwMDAgbg0KMDAwMDA0NTA0MSAwMDAwMCBuDQowMDAwMDQ1MDc3IDAwMDAwIG4NCjAw MDAwNDUwOTkgMDAwMDAgbg0KMDAwMDA0NjcyNyAwMDAwMCBuDQowMDAwMDQ2ODgxIDAwMDAwIG4N CjAwMDAwNDcwMTggMDAwMDAgbg0KMDAwMDA0ODU3OCAwMDAwMCBuDQowMDAwMDQ4NjgzIDAwMDAw IG4NCjAwMDAwNDg3NjcgMDAwMDAgbg0KMDAwMDA1MDE2MyAwMDAwMCBuDQowMDAwMDUwODU5IDAw MDAwIG4NCjAwMDAwNTA4ODAgMDAwMDAgbg0KMDAwMDA1MTAwOSAwMDAwMCBuDQp0cmFpbGVyDTw8 DS9TaXplIDQ0DS9JRFs8NDM3OGE5NjEyNjUxNGQ2Mjc0NGRhMGFhZTlkYjU4NzU+PDQzNzhhOTYx MjY1MTRkNjI3NDRkYTBhYWU5ZGI1ODc1Pl0NPj4Nc3RhcnR4cmVmDTE3Mw0lJUVPRg0= ------=_NextPart_000_0028_01C2E890.9DBAE0C0-- ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-12 17:12 ` John Burch @ 2003-03-12 21:43 ` Steve Wahl 2003-03-12 22:17 ` John Burch ` (2 more replies) 0 siblings, 3 replies; 20+ messages in thread From: Steve Wahl @ 2003-03-12 21:43 UTC (permalink / raw) To: linux-mtd On Wed, Mar 12, 2003 at 12:12:12PM -0500, John Burch wrote: > AMD's own method from code they provide is shown below... > > By the way, AMD specifically mentions having to check DQ6/7 again > after DQ5=1 because of the possibility that DQ5=1 simultaneous with > toggling stopping. The app note I referred to before (attached this > time) describes this in some detail. I agree with this. > The status register (including DQ5) won't reflect actual data until > a reset command is issued, This I think is a misunderstanding or misstatement on your part. The reads WILL return to actual data without a reset upon successful completion of the operation. Only on a failure does software need to issue the reset to return to reading data! The app note you attached agrees with me on this. > so I think the concern about DQ5=1 because erased data (0xff) is > read instead of status is not valid. I disagree. This concern is indeed valid, and is the primary reason you must check for toggling AFTER noticing DQ5=1 in the first place. Note that cfiflash below does not handle interleave nor bit endianness, so you can't adopt it directly. --> Steve > John > > >From AMD's cfiflash.c: > > /*********************************************************************/ > /* Flash_status utilizes the DQ6, DQ5, and DQ3 polling algorithms */ > /* described in the flash data book. It can quickly ascertain the */ > /* operational status of the flash device, and return an */ > /* appropriate status code (defined in flash.h) */ > /*********************************************************************/ > > int flash_status(word far *fp) > { > unsigned char d, t; > int retry = 1; > > again: > > d = *fp; /* read data */ > t = d ^ *fp; /* read it again and see what toggled */ > > if (t == 0) { /* no toggles, nothing's happening */ > return STATUS_READY; > } > else if (t == 0x04) { /* erase-suspend */ > if (retry--) goto again; /* may have been write > completion */ > return STATUS_ERSUSP; > } > else if (t & 0x40) { > if (d & 0x20) { /* timeout */ > return STATUS_TIMEOUT; > } > else { > return STATUS_BUSY; > } > } > > if (retry--) goto again; /* may have been write completion > */ > > return STATUS_ERROR; > } > > > > > -----Original Message----- > > From: linux-mtd-admin at lists.infradead.org > > [mailto:linux-mtd-admin at lists.infradead.org] On Behalf Of Steve Wahl > > Sent: Wednesday, March 12, 2003 11:28 AM > > To: Thayne Harbaugh > > Cc: linux-mtd at lists.infradead.org > > Subject: Re: DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy > > Queen 5 warning) > > > > > > Thayne, > > > > I have a patch that I was given permission to check in, but > > never got around to it, that covers a similar "DQ5 raised" problem. > > > > I would wager you are running into the same problem I did, > > and that your chips compatibly support DQ5, if not as a > > watchdog, at least by holding it low while programming. > > > > Can you look at my previous posts on this, try my patch (if > > you don't have interleaved chips -- contact me if you do), > > and see if it works for you? > > > > http://lists.infradead.org/pipermail/linux-mtd/2003-January/00 > > 6780.html > > > > --> Steve > > > > > > On Tue, Mar 11, 2003 at 05:25:15PM -0700, Thayne Harbaugh wrote: > > > For some reason I am confused: I get the feeling that what > > I'm trying > > > to understand is obvious - I just can't see the forest for > > the trees. > > > Will someone help me understand? > > > > > > cfi_cmdset_0002.c has several functions that use dq5 and dq6 for > > > monitoring the status of erase and write operations: > > > > > > dq6 = CMD(1<<6); > > > dq5 = CMD(1<<5); > > > > > > Apparently, from the code dq6 toggles during erase/read > > operations and > > > dq5 is low until the erase/read operation times out and > > then goes high > > > (somewhat like a watchdog bit). > > > > > > My understanding, at least for the SST 49LF040 and PMC Pm49L004 is > > > that dq6 toggles during erase/write and dq7 is inverted until the > > > erase/write operation completes. This causes me to expect > > to see the > > > following code rather than what is written above (not to > > mention that > > > most everything in do_write_one_word() should be adapted for dq7 > > > invert): > > > > > > dq7 = CMD(1<<7); /* invert */ > > > dq6 = CMD(1<<6); /* toggle */ > > > > > > The differences give me the feeling that there really are two > > > different classes of cfi_cmdset_0002 - those devices that > > have a dq5 > > > watchdog and those devices that don't have the watchdog, but have a > > > bit inverter on dq7. > > > > > > Am I not understanding what happens on bits 0-5 during an > > erase/write > > > operation? The PMC and SST chips don't mention a thing about dq5 > > > behavior. If they don't have the dq5 watchdog timer then they will > > > behave in an undefined way (depending on the state of bit 5 in the > > > written word) with the current dq5 checking. This explains > > the many > > > warnings I see with the SST and PMC chips in do_write_oneword(), > > > > > > "Warning: DQ5 raised while program operation was in > > progress, however > > > operation completed OK" > > > > > > Around here we refer to this as the "Dairy Queen 5" warning. > > > > > > Obviosly, during an erase that completes prior to dq5 being > > read-back, > > > dq5 will be high and the current algorithm is erroneously correct. > > > This can explain why I have not seen the same message in > > > do_erase_oneblock(). > > > > > > Furthermore, the SST documentation on page 10 refers to "spurios > > > rejection" of good writes - differentiating between a write that > > > succeeds that appears to fail and a write that fails. It > > says that a > > > write that appears to fail needs to be read back two more times > > > successfully to filter out spurious rejection. > > > > > > Comments? What should change to improve the operation completion > > > check? Should cfi_cmdset_0002 be adapted to handle > > multiple types of > > > polling or should another command set be written? > > > > > > -- > > > Thayne Harbaugh > > > Linux Networx > > > > > > > > ______________________________________________________ > > Linux MTD discussion mailing list > > http://lists.infradead.org/mailman/listinfo/linux-mtd/ > > ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-12 21:43 ` Steve Wahl @ 2003-03-12 22:17 ` John Burch 2003-03-13 7:17 ` David Woodhouse 2003-03-17 15:54 ` Thayne Harbaugh 2 siblings, 0 replies; 20+ messages in thread From: John Burch @ 2003-03-12 22:17 UTC (permalink / raw) To: linux-mtd > -----Original Message----- > From: Steve Wahl [mailto:swahl at brecis.com]=20 > Sent: Wednesday, March 12, 2003 4:43 PM > To: John Burch > Cc: 'Thayne Harbaugh'; linux-mtd at lists.infradead.org > Subject: Re: DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy=20 > Queen 5 warning) >=20 >=20 > On Wed, Mar 12, 2003 at 12:12:12PM -0500, John Burch wrote: > > AMD's own method from code they provide is shown below... > >=20 > > By the way, AMD specifically mentions having to check DQ6/7 again=20 > > after DQ5=3D1 because of the possibility that DQ5=3D1 simultaneous = with=20 > > toggling stopping. The app note I referred to before (attached this > > time) describes this in some detail. >=20 > I agree with this. >=20 > > The status register (including DQ5) won't reflect actual=20 > data until a=20 > > reset command is issued, >=20 > This I think is a misunderstanding or misstatement on your=20 > part. The reads WILL return to actual data without a reset=20 > upon successful completion of the operation. Only on a=20 > failure does software need to issue the reset to return to=20 > reading data! >=20 > The app note you attached agrees with me on this. You are correct, sir. >=20 > > so I think the concern about DQ5=3D1 because erased data=20 > (0xff) is read=20 > > instead of status is not valid. >=20 > I disagree. This concern is indeed valid, and is the primary=20 > reason you must check for toggling AFTER noticing DQ5=3D1 in=20 > the first place. You're right, again. I'd focused in on the error case where a reset has to be issued when DQ5 goes high due to an actual timeout, and not the normal case where the device returns to "read" mode automatically upon successful completion of the command. Thanks for straightening me out. >=20 > Note that cfiflash below does not handle interleave nor bit=20 > endianness, so you can't adopt it directly. >=20 > --> Steve >=20 > > John > >=20 > > >From AMD's cfiflash.c: > >=20 > >=20 > /************************************************************* > ********/ > > /* Flash_status utilizes the DQ6, DQ5, and DQ3 polling=20 > algorithms */ > > /* described in the flash data book. It can quickly=20 > ascertain the */ > > /* operational status of the flash device, and return an =20 > */ > > /* appropriate status code (defined in flash.h) =20 > */ > >=20 > /********************************************************************* > > / > > =20 > > int flash_status(word far *fp) > > { > > unsigned char d, t; > > int retry =3D 1; > >=20 > > again: > >=20 > > d =3D *fp; /* read data */ > > t =3D d ^ *fp; /* read it again and see what toggled */ > >=20 > > if (t =3D=3D 0) { /* no toggles, nothing's happening */ > > return STATUS_READY; > > } > > else if (t =3D=3D 0x04) { /* erase-suspend */ > > if (retry--) goto again; /* may have been write > > completion */ > > return STATUS_ERSUSP; > > } > > else if (t & 0x40) { > > if (d & 0x20) { /* timeout */ > > return STATUS_TIMEOUT; > > } > > else { > > return STATUS_BUSY; > > } > > } > >=20 > > if (retry--) goto again; /* may have been write completion > > */ > >=20 > > return STATUS_ERROR; > > } > >=20 > >=20 > >=20 > > > -----Original Message----- > > > From: linux-mtd-admin at lists.infradead.org > > > [mailto:linux-mtd-admin at lists.infradead.org] On Behalf Of=20 > Steve Wahl > > > Sent: Wednesday, March 12, 2003 11:28 AM > > > To: Thayne Harbaugh > > > Cc: linux-mtd at lists.infradead.org > > > Subject: Re: DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy=20 > > > Queen 5 warning) > > >=20 > > >=20 > > > Thayne, > > >=20 > > > I have a patch that I was given permission to check in, but > > > never got around to it, that covers a similar "DQ5=20 > raised" problem. > > >=20 > > > I would wager you are running into the same problem I did, > > > and that your chips compatibly support DQ5, if not as a=20 > > > watchdog, at least by holding it low while programming. > > >=20 > > > Can you look at my previous posts on this, try my patch (if > > > you don't have interleaved chips -- contact me if you do),=20 > > > and see if it works for you? > > >=20 > > > http://lists.infradead.org/pipermail/linux-mtd/2003-January/00 > > > 6780.html > > >=20 > > > --> Steve > > >=20 > > >=20 > > > On Tue, Mar 11, 2003 at 05:25:15PM -0700, Thayne Harbaugh wrote: > > > > For some reason I am confused: I get the feeling that what > > > I'm trying > > > > to understand is obvious - I just can't see the forest for > > > the trees. > > > > Will someone help me understand? > > > >=20 > > > > cfi_cmdset_0002.c has several functions that use dq5 and dq6 for > > > > monitoring the status of erase and write operations: > > > >=20 > > > > dq6 =3D CMD(1<<6); > > > > dq5 =3D CMD(1<<5); > > > >=20 > > > > Apparently, from the code dq6 toggles during erase/read > > > operations and > > > > dq5 is low until the erase/read operation times out and > > > then goes high > > > > (somewhat like a watchdog bit). > > > >=20 > > > > My understanding, at least for the SST 49LF040 and PMC=20 > Pm49L004 is > > > > that dq6 toggles during erase/write and dq7 is inverted=20 > until the=20 > > > > erase/write operation completes. This causes me to expect=20 > > > to see the > > > > following code rather than what is written above (not to > > > mention that > > > > most everything in do_write_one_word() should be adapted for dq7 > > > > invert): > > > >=20 > > > > dq7 =3D CMD(1<<7); /* invert */ > > > > dq6 =3D CMD(1<<6); /* toggle */ > > > >=20 > > > > The differences give me the feeling that there really are two > > > > different classes of cfi_cmdset_0002 - those devices that=20 > > > have a dq5 > > > > watchdog and those devices that don't have the=20 > watchdog, but have=20 > > > > a > > > > bit inverter on dq7. > > > >=20 > > > > Am I not understanding what happens on bits 0-5 during an > > > erase/write > > > > operation? The PMC and SST chips don't mention a thing=20 > about dq5 > > > > behavior. If they don't have the dq5 watchdog timer=20 > then they will=20 > > > > behave in an undefined way (depending on the state of=20 > bit 5 in the=20 > > > > written word) with the current dq5 checking. This explains=20 > > > the many > > > > warnings I see with the SST and PMC chips in do_write_oneword(), > > > >=20 > > > > "Warning: DQ5 raised while program operation was in > > > progress, however > > > > operation completed OK" > > > >=20 > > > > Around here we refer to this as the "Dairy Queen 5" warning. > > > >=20 > > > > Obviosly, during an erase that completes prior to dq5 being > > > read-back, > > > > dq5 will be high and the current algorithm is=20 > erroneously correct. > > > > This can explain why I have not seen the same message in=20 > > > > do_erase_oneblock(). > > > >=20 > > > > Furthermore, the SST documentation on page 10 refers to "spurios > > > > rejection" of good writes - differentiating between a=20 > write that=20 > > > > succeeds that appears to fail and a write that fails. It=20 > > > says that a > > > > write that appears to fail needs to be read back two more times > > > > successfully to filter out spurious rejection. > > > >=20 > > > > Comments? What should change to improve the operation=20 > completion > > > > check? Should cfi_cmdset_0002 be adapted to handle=20 > > > multiple types of > > > > polling or should another command set be written? > > > >=20 > > > > -- > > > > Thayne Harbaugh > > > > Linux Networx > > >=20 > > >=20 > > >=20 > > > ______________________________________________________ > > > Linux MTD discussion mailing list=20 > > > http://lists.infradead.org/mailman/listinfo/linux-mtd/ > > >=20 >=20 >=20 >=20 ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-12 21:43 ` Steve Wahl 2003-03-12 22:17 ` John Burch @ 2003-03-13 7:17 ` David Woodhouse 2003-03-13 7:26 ` Russ Dill 2003-03-17 15:54 ` Thayne Harbaugh 2 siblings, 1 reply; 20+ messages in thread From: David Woodhouse @ 2003-03-13 7:17 UTC (permalink / raw) To: linux-mtd On Wed, 2003-03-12 at 21:43, Steve Wahl wrote: > Note that cfiflash below does not handle interleave nor bit > endianness, so you can't adopt it directly. And under what licence is it available? -- dwmw2 ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-13 7:17 ` David Woodhouse @ 2003-03-13 7:26 ` Russ Dill 0 siblings, 0 replies; 20+ messages in thread From: Russ Dill @ 2003-03-13 7:26 UTC (permalink / raw) To: linux-mtd On Thu, 2003-03-13 at 00:17, David Woodhouse wrote: > On Wed, 2003-03-12 at 21:43, Steve Wahl wrote: > > > Note that cfiflash below does not handle interleave nor bit > > endianness, so you can't adopt it directly. > > And under what licence is it available? here is some GPL code written by someone who's never looked at the AMD code (until the previous email) http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/blob/blob/src/blob/amd32.c?rev=1.6&content-type=text/vnd.viewcvs-markup its a little complex because it handles two chips in an interleaved configuration. ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-12 21:43 ` Steve Wahl 2003-03-12 22:17 ` John Burch 2003-03-13 7:17 ` David Woodhouse @ 2003-03-17 15:54 ` Thayne Harbaugh 2003-03-17 16:09 ` John Burch 2003-03-17 16:19 ` Steve Wahl 2 siblings, 2 replies; 20+ messages in thread From: Thayne Harbaugh @ 2003-03-17 15:54 UTC (permalink / raw) To: linux-mtd --=-cETyYQUhDowe+f8spAYE Content-Type: text/plain Content-Transfer-Encoding: quoted-printable On Wed, 2003-03-12 at 14:43, Steve Wahl wrote: > On Wed, Mar 12, 2003 at 12:12:12PM -0500, John Burch wrote: <snip> > > The status register (including DQ5) won't reflect actual data until > > a reset command is issued, >=20 > This I think is a misunderstanding or misstatement on your part. The > reads WILL return to actual data without a reset upon successful > completion of the operation. Only on a failure does software need to > issue the reset to return to reading data! Big question: how is it know if status bits are being read or the real data that was written to an address? I have read many data sheets and I don't recall any of them discussing this concern. > --> Steve >=20 > > John > >=20 > > >From AMD's cfiflash.c: > >=20 > > /*********************************************************************/ > > /* Flash_status utilizes the DQ6, DQ5, and DQ3 polling algorithms */ > > /* described in the flash data book. It can quickly ascertain the */ > > /* operational status of the flash device, and return an */ > > /* appropriate status code (defined in flash.h) */ > > /*********************************************************************/ > > =20 > > int flash_status(word far *fp) > > { > > unsigned char d, t; > > int retry =3D 1; > >=20 > > again: > >=20 > > d =3D *fp; /* read data */ > > t =3D d ^ *fp; /* read it again and see what toggled */ > >=20 > > if (t =3D=3D 0) { /* no toggles, nothing's happening */ > > return STATUS_READY; > > } > > else if (t =3D=3D 0x04) { /* erase-suspend */ > > if (retry--) goto again; /* may have been write > > completion */ > > return STATUS_ERSUSP; > > } > > else if (t & 0x40) { > > if (d & 0x20) { /* timeout */ > > return STATUS_TIMEOUT; > > } > > else { > > return STATUS_BUSY; > > } > > } > >=20 > > if (retry--) goto again; /* may have been write completion > > */ > >=20 > > return STATUS_ERROR; > > } > >=20 > >=20 > >=20 > > > -----Original Message----- > > > From: linux-mtd-admin at lists.infradead.org=20 > > > [mailto:linux-mtd-admin at lists.infradead.org] On Behalf Of Steve Wahl > > > Sent: Wednesday, March 12, 2003 11:28 AM > > > To: Thayne Harbaugh > > > Cc: linux-mtd at lists.infradead.org > > > Subject: Re: DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy=20 > > > Queen 5 warning) > > >=20 > > >=20 > > > Thayne,=20 > > >=20 > > > I have a patch that I was given permission to check in, but=20 > > > never got around to it, that covers a similar "DQ5 raised" problem. > > >=20 > > > I would wager you are running into the same problem I did,=20 > > > and that your chips compatibly support DQ5, if not as a=20 > > > watchdog, at least by holding it low while programming. > > >=20 > > > Can you look at my previous posts on this, try my patch (if=20 > > > you don't have interleaved chips -- contact me if you do),=20 > > > and see if it works for you? > > >=20 > > > http://lists.infradead.org/pipermail/linux-mtd/2003-January/00 > > > 6780.html > > >=20 > > > --> Steve > > >=20 > > >=20 > > > On Tue, Mar 11, 2003 at 05:25:15PM -0700, Thayne Harbaugh wrote: > > > > For some reason I am confused: I get the feeling that what=20 > > > I'm trying=20 > > > > to understand is obvious - I just can't see the forest for=20 > > > the trees. =20 > > > > Will someone help me understand? > > > >=20 > > > > cfi_cmdset_0002.c has several functions that use dq5 and dq6 for=20 > > > > monitoring the status of erase and write operations: > > > >=20 > > > > dq6 =3D CMD(1<<6); > > > > dq5 =3D CMD(1<<5); > > > >=20 > > > > Apparently, from the code dq6 toggles during erase/read=20 > > > operations and=20 > > > > dq5 is low until the erase/read operation times out and=20 > > > then goes high=20 > > > > (somewhat like a watchdog bit). > > > >=20 > > > > My understanding, at least for the SST 49LF040 and PMC Pm49L004 is=20 > > > > that dq6 toggles during erase/write and dq7 is inverted until the=20 > > > > erase/write operation completes. This causes me to expect=20 > > > to see the=20 > > > > following code rather than what is written above (not to=20 > > > mention that=20 > > > > most everything in do_write_one_word() should be adapted for dq7=20 > > > > invert): > > > >=20 > > > > dq7 =3D CMD(1<<7); /* invert */ > > > > dq6 =3D CMD(1<<6); /* toggle */ > > > >=20 > > > > The differences give me the feeling that there really are two=20 > > > > different classes of cfi_cmdset_0002 - those devices that=20 > > > have a dq5=20 > > > > watchdog and those devices that don't have the watchdog, but have a= =20 > > > > bit inverter on dq7. > > > >=20 > > > > Am I not understanding what happens on bits 0-5 during an=20 > > > erase/write=20 > > > > operation? The PMC and SST chips don't mention a thing about dq5=20 > > > > behavior. If they don't have the dq5 watchdog timer then they will= =20 > > > > behave in an undefined way (depending on the state of bit 5 in the=20 > > > > written word) with the current dq5 checking. This explains=20 > > > the many=20 > > > > warnings I see with the SST and PMC chips in do_write_oneword(), > > > >=20 > > > > "Warning: DQ5 raised while program operation was in=20 > > > progress, however=20 > > > > operation completed OK" > > > >=20 > > > > Around here we refer to this as the "Dairy Queen 5" warning. > > > >=20 > > > > Obviosly, during an erase that completes prior to dq5 being=20 > > > read-back,=20 > > > > dq5 will be high and the current algorithm is erroneously correct. = =20 > > > > This can explain why I have not seen the same message in=20 > > > > do_erase_oneblock(). > > > >=20 > > > > Furthermore, the SST documentation on page 10 refers to "spurios=20 > > > > rejection" of good writes - differentiating between a write that=20 > > > > succeeds that appears to fail and a write that fails. It=20 > > > says that a=20 > > > > write that appears to fail needs to be read back two more times=20 > > > > successfully to filter out spurious rejection. > > > >=20 > > > > Comments? What should change to improve the operation completion=20 > > > > check? Should cfi_cmdset_0002 be adapted to handle=20 > > > multiple types of=20 > > > > polling or should another command set be written? > > > >=20 > > > > -- > > > > Thayne Harbaugh > > > > Linux Networx > > >=20 > > >=20 > > >=20 > > > ______________________________________________________ > > > Linux MTD discussion mailing list > > > http://lists.infradead.org/mailman/listinfo/linux-mtd/ > > >=20 >=20 >=20 >=20 > ______________________________________________________ > Linux MTD discussion mailing list > http://lists.infradead.org/mailman/listinfo/linux-mtd/ --=20 Thayne Harbaugh Linux Networx --=-cETyYQUhDowe+f8spAYE Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6 (GNU/Linux) Comment: For info see http://www.gnupg.org iD8DBQA+de+tfsBPTKE6HMkRAjjgAJ9QETLlxInaPZtW4W/5BY3vz7dU8ACfTnFo tZfaspvL/3AAR1ebfrQDwjU= =pFkZ -----END PGP SIGNATURE----- --=-cETyYQUhDowe+f8spAYE-- ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-17 15:54 ` Thayne Harbaugh @ 2003-03-17 16:09 ` John Burch 2003-03-17 16:19 ` Steve Wahl 1 sibling, 0 replies; 20+ messages in thread From: John Burch @ 2003-03-17 16:09 UTC (permalink / raw) To: linux-mtd > -----Original Message----- > From: Thayne Harbaugh [mailto:tharbaugh at lnxi.com]=20 > Sent: Monday, March 17, 2003 10:54 AM > To: Steve Wahl > Cc: John Burch; linux-mtd at lists.infradead.org > Subject: Re: DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy=20 > Queen 5 warning) >=20 <snip> >=20 >=20 > Big question: how is it know if status bits are being read or=20 > the real data that was written to an address? I have read=20 > many data sheets and I don't recall any of them discussing=20 > this concern. I believe that if DQ6 is not toggling, then you're reading actual data. If DQ6 is toggling and DQ5=3D0, then you're reading Status and the device is still busy. If DQ6 is toggling and DQ5=3D1, You're still reading status and DQ6 must be checked again. If toggling, operation timed out, you're still reading status, and reset command must be issued. If not toggling, operation completed, and you're reading data. (At least this is how AMD describes it.) John <snip> ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-17 15:54 ` Thayne Harbaugh 2003-03-17 16:09 ` John Burch @ 2003-03-17 16:19 ` Steve Wahl 2003-03-17 18:27 ` Thayne Harbaugh 1 sibling, 1 reply; 20+ messages in thread From: Steve Wahl @ 2003-03-17 16:19 UTC (permalink / raw) To: linux-mtd On Mon, Mar 17, 2003 at 08:54:21AM -0700, Thayne Harbaugh wrote: > On Wed, 2003-03-12 at 14:43, Steve Wahl wrote: > > On Wed, Mar 12, 2003 at 12:12:12PM -0500, John Burch wrote: > > <snip> > > > > The status register (including DQ5) won't reflect actual data until > > > a reset command is issued, > > > > This I think is a misunderstanding or misstatement on your part. The > > reads WILL return to actual data without a reset upon successful > > completion of the operation. Only on a failure does software need to > > issue the reset to return to reading data! > > Big question: how is it know if status bits are being read or the real > data that was written to an address? I have read many data sheets and I > don't recall any of them discussing this concern. Easy, at least in theory. If two consecutive reads are the same, then the DQ6 isn't toggling any longer, therfore you are reading data. Only if the two consecutive reads are different can you assume that you read the status register -- and you can only assume the FIRST read was a status register, because the second read could have been after changing to data mode. But, outside of easy theories, there's a couple of gotchas in there. I've read at least one data sheet that suggested that the switch from the status register to the data "register" happens asyncronously to processor reads, so it is possible, though very unlikely, to get some bits from the status register and some bits from the actual data within a single read -- if the read happens at the exact instance that the chip is switching from one mode to the other. I have never seen any code that takes this into account -- sample code, data sheet flow charts, etc. I think this may, however, have something to do with what you wrote: "I do know, however, that several manufactures recommend that the final status should be checked an additional two times before a success is reported." I'd be interested to see specific data sheets or application notes that do this. --> Steve ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-17 16:19 ` Steve Wahl @ 2003-03-17 18:27 ` Thayne Harbaugh 2003-03-18 16:51 ` Steve Wahl 0 siblings, 1 reply; 20+ messages in thread From: Thayne Harbaugh @ 2003-03-17 18:27 UTC (permalink / raw) To: linux-mtd --=-EvrZnUndJESZ8BzsyWWf Content-Type: text/plain Content-Transfer-Encoding: quoted-printable On Mon, 2003-03-17 at 09:19, Steve Wahl wrote: > On Mon, Mar 17, 2003 at 08:54:21AM -0700, Thayne Harbaugh wrote: <snip> > > I do know, however, that several > > manufactures recommend that the final status should be checked an > > additional two times before a success is reported. > I'd be interested > to see specific data sheets or application notes that do this. What I stated is not completely accurate. Here is what SST states on page 14 of _4_Mbit_LPC_Flash_SST49LF040_ in the Write Operation Status Detection section: The actual completion of the nonvolatile write is asynchronous with the system; therefore, either a Data# Palling or Toggle Bit read may be simultaneous with the completion of the Write cycle. If this occurs, the system may possibly get an erroneous result, i.e., valid data may appear to conflict with either DQ7 or DQ6. In order to prevent spurious rejection, if an erroneous result occurs, the software routine should include a loop to read the accessed location an additional two (2) times. If both reads are valid, then the device has completed the Write cycle, otherwise the rejection is valid. >=20 >=20 > --> Steve >=20 > ______________________________________________________ > Linux MTD discussion mailing list > http://lists.infradead.org/mailman/listinfo/linux-mtd/ --=20 Thayne Harbaugh Linux Networx --=-EvrZnUndJESZ8BzsyWWf Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6 (GNU/Linux) Comment: For info see http://www.gnupg.org iD8DBQA+dhOdfsBPTKE6HMkRAs74AJ9ehcvP2+OOFJETNselB5iIHK0fjwCdE2Z9 J0NvOYO2El7enuc/AoHNxA0= =wDoQ -----END PGP SIGNATURE----- --=-EvrZnUndJESZ8BzsyWWf-- ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-17 18:27 ` Thayne Harbaugh @ 2003-03-18 16:51 ` Steve Wahl 2003-03-18 17:22 ` Thayne Harbaugh 0 siblings, 1 reply; 20+ messages in thread From: Steve Wahl @ 2003-03-18 16:51 UTC (permalink / raw) To: linux-mtd On Mon, Mar 17, 2003 at 11:27:41AM -0700, Thayne Harbaugh wrote: > On Mon, 2003-03-17 at 09:19, Steve Wahl wrote: > > On Mon, Mar 17, 2003 at 08:54:21AM -0700, Thayne Harbaugh wrote: > > <snip> > > > > I do know, however, that several > > > manufactures recommend that the final status should be checked an > > > additional two times before a success is reported. > > > > I'd be interested > > to see specific data sheets or application notes that do this. > > What I stated is not completely accurate. Here is what SST states on > page 14 of _4_Mbit_LPC_Flash_SST49LF040_ in the Write Operation Status > Detection section: > > The actual completion of the nonvolatile write is asynchronous with the > system; therefore, either a Data# Palling or Toggle Bit read may be > simultaneous with the completion of the Write cycle. If this occurs, > the system may possibly get an erroneous result, i.e., valid data may > appear to conflict with either DQ7 or DQ6. In order to prevent spurious > rejection, if an erroneous result occurs, the software routine should > include a loop to read the accessed location an additional two (2) > times. If both reads are valid, then the device has completed the Write > cycle, otherwise the rejection is valid. Ahh. If I read this correctly, if you are about to report an error you should read two more times to make sure it's still there. So your original wording should be "the final status should be checked an additional two times before a *failure* is reported." You could legally / reasonably report success the instant you detect it. Do you agree? It is somewhat funny that if this was followed, I wouldn't have run into the "DQ5 detected, but things seem OK" warning (can't remember the original wording, sorry). --> Steve ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-18 16:51 ` Steve Wahl @ 2003-03-18 17:22 ` Thayne Harbaugh 0 siblings, 0 replies; 20+ messages in thread From: Thayne Harbaugh @ 2003-03-18 17:22 UTC (permalink / raw) To: linux-mtd --=-WR4q0zDjS2E9vaYtdMRV Content-Type: text/plain Content-Transfer-Encoding: quoted-printable On Tue, 2003-03-18 at 09:51, Steve Wahl wrote: > On Mon, Mar 17, 2003 at 11:27:41AM -0700, Thayne Harbaugh wrote: > > On Mon, 2003-03-17 at 09:19, Steve Wahl wrote: > > > On Mon, Mar 17, 2003 at 08:54:21AM -0700, Thayne Harbaugh wrote: > >=20 > > <snip> > >=20 > > > > I do know, however, that several > > > > manufactures recommend that the final status should be checked an > > > > additional two times before a success is reported. > >=20 > >=20 > > > I'd be interested > > > to see specific data sheets or application notes that do this. > >=20 > > What I stated is not completely accurate. Here is what SST states on > > page 14 of _4_Mbit_LPC_Flash_SST49LF040_ in the Write Operation Status > > Detection section: > >=20 > > The actual completion of the nonvolatile write is asynchronous with the > > system; therefore, either a Data# Palling or Toggle Bit read may be > > simultaneous with the completion of the Write cycle. If this occurs, > > the system may possibly get an erroneous result, i.e., valid data may > > appear to conflict with either DQ7 or DQ6. In order to prevent spuriou= s > > rejection, if an erroneous result occurs, the software routine should > > include a loop to read the accessed location an additional two (2) > > times. If both reads are valid, then the device has completed the Writ= e > > cycle, otherwise the rejection is valid. >=20 > Ahh. If I read this correctly, if you are about to report an error > you should read two more times to make sure it's still there. >=20 > So your original wording should be "the final status should be checked > an additional two times before a *failure* is reported." You could > legally / reasonably report success the instant you detect it. >=20 > Do you agree? Yes, that's exactly how I interpret it after re-reading it. I have seen this statement in more than one vendor's documentation. This is also the way I am writing my AMD simplified command set driver. The part that I still scratch my head about is why it needs to read correctly on _both_ reads. Why is it not good enough to have success on the last read? > It is somewhat funny that if this was followed, I wouldn't have run > into the "DQ5 detected, but things seem OK" warning (can't remember > the original wording, sorry).=20 Yes, that would have eliminated the error. >=20 > --> Steve --=20 Thayne Harbaugh Linux Networx --=-WR4q0zDjS2E9vaYtdMRV Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6 (GNU/Linux) Comment: For info see http://www.gnupg.org iD8DBQA+d1XpfsBPTKE6HMkRAuNKAJ9QKThjRWAbE7yrOqbSS9ojRPUA9wCfSvOl uxoA+QJng3T5UgutVXIem2c= =r7zg -----END PGP SIGNATURE----- --=-WR4q0zDjS2E9vaYtdMRV-- ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-12 16:27 ` Steve Wahl 2003-03-12 17:12 ` John Burch @ 2003-03-17 15:40 ` Thayne Harbaugh 2003-03-17 18:38 ` Thayne Harbaugh 1 sibling, 1 reply; 20+ messages in thread From: Thayne Harbaugh @ 2003-03-17 15:40 UTC (permalink / raw) To: linux-mtd --=-64s8WUTVLomH51lxT+h7 Content-Type: text/plain Content-Transfer-Encoding: quoted-printable On Wed, 2003-03-12 at 09:27, Steve Wahl wrote: > Thayne,=20 >=20 > I have a patch that I was given permission to check in, but never got > around to it, that covers a similar "DQ5 raised" problem. Speaking of never getting around to things - I'm finally replying to your email. > I would wager you are running into the same problem I did, and that > your chips compatibly support DQ5, if not as a watchdog, at least by > holding it low while programming. I have sent email to PMC and the official response is that the _only_ bits that reflect erase/write operation status are I/O7 and I/O6 (effectively DQ7 and DQ6). I/O7 is inverted data during the operation and I/O6 toggles. The PMC response was that AMD status bits aren't supported. In practice, however, DQ5 is low during erase/write operations. I am uneasy about using undocumented features. > Can you look at my previous posts on this, try my patch (if you don't > have interleaved chips -- contact me if you do), No, I don't have interleaved chips. > and see if it works > for you? >=20 > http://lists.infradead.org/pipermail/linux-mtd/2003-January/006780.html I have looked through your patch and agree that it addresses a legal state that currently triggers a warning and should not. I do know, however, that several manufactures recommend that the final status should be checked an additional two times before a success is reported. > --> Steve >=20 >=20 > On Tue, Mar 11, 2003 at 05:25:15PM -0700, Thayne Harbaugh wrote: > > For some reason I am confused: I get the feeling that what I'm trying t= o > > understand is obvious - I just can't see the forest for the trees. Wil= l > > someone help me understand? > >=20 > > cfi_cmdset_0002.c has several functions that use dq5 and dq6 for > > monitoring the status of erase and write operations: > >=20 > > dq6 =3D CMD(1<<6); > > dq5 =3D CMD(1<<5); > >=20 > > Apparently, from the code dq6 toggles during erase/read operations and > > dq5 is low until the erase/read operation times out and then goes high > > (somewhat like a watchdog bit). > >=20 > > My understanding, at least for the SST 49LF040 and PMC Pm49L004 is that > > dq6 toggles during erase/write and dq7 is inverted until the erase/writ= e > > operation completes. This causes me to expect to see the following cod= e > > rather than what is written above (not to mention that most everything > > in do_write_one_word() should be adapted for dq7 invert): > >=20 > > dq7 =3D CMD(1<<7); /* invert */ > > dq6 =3D CMD(1<<6); /* toggle */ > >=20 > > The differences give me the feeling that there really are two different > > classes of cfi_cmdset_0002 - those devices that have a dq5 watchdog and > > those devices that don't have the watchdog, but have a bit inverter on > > dq7. > >=20 > > Am I not understanding what happens on bits 0-5 during an erase/write > > operation? The PMC and SST chips don't mention a thing about dq5 > > behavior. If they don't have the dq5 watchdog timer then they will > > behave in an undefined way (depending on the state of bit 5 in the > > written word) with the current dq5 checking. This explains the many > > warnings I see with the SST and PMC chips in do_write_oneword(), > >=20 > > "Warning: DQ5 raised while program operation was in progress, however > > operation completed OK" > >=20 > > Around here we refer to this as the "Dairy Queen 5" warning. > >=20 > > Obviosly, during an erase that completes prior to dq5 being read-back, > > dq5 will be high and the current algorithm is erroneously correct. Thi= s > > can explain why I have not seen the same message in do_erase_oneblock()= . > >=20 > > Furthermore, the SST documentation on page 10 refers to "spurios > > rejection" of good writes - differentiating between a write that > > succeeds that appears to fail and a write that fails. It says that a > > write that appears to fail needs to be read back two more times > > successfully to filter out spurious rejection. > >=20 > > Comments? What should change to improve the operation completion > > check? Should cfi_cmdset_0002 be adapted to handle multiple types of > > polling or should another command set be written? > >=20 > > --=20 > > Thayne Harbaugh > > Linux Networx >=20 >=20 >=20 > ______________________________________________________ > Linux MTD discussion mailing list > http://lists.infradead.org/mailman/listinfo/linux-mtd/ --=20 Thayne Harbaugh Linux Networx --=-64s8WUTVLomH51lxT+h7 Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6 (GNU/Linux) Comment: For info see http://www.gnupg.org iD8DBQA+dexufsBPTKE6HMkRAlp6AJ9GWe9I6x7WezK4AZrXLAwosBiwTwCfZQfj ZOyJRWSWhmCLtdF4/kk084o= =637Y -----END PGP SIGNATURE----- --=-64s8WUTVLomH51lxT+h7-- ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-17 15:40 ` Thayne Harbaugh @ 2003-03-17 18:38 ` Thayne Harbaugh 2003-03-19 0:23 ` Thayne Harbaugh 0 siblings, 1 reply; 20+ messages in thread From: Thayne Harbaugh @ 2003-03-17 18:38 UTC (permalink / raw) To: linux-mtd --=-S5ixrRaefhmMdHKqH2Zj Content-Type: text/plain Content-Transfer-Encoding: quoted-printable On Mon, 2003-03-17 at 08:40, Thayne Harbaugh wrote: > On Wed, 2003-03-12 at 09:27, Steve Wahl wrote: <snip> > > I would wager you are running into the same problem I did, and that > > your chips compatibly support DQ5, if not as a watchdog, at least by > > holding it low while programming. >=20 > I have sent email to PMC and the official response is that the _only_ > bits that reflect erase/write operation status are I/O7 and I/O6 > (effectively DQ7 and DQ6). I/O7 is inverted data during the operation > and I/O6 toggles. The PMC response was that AMD status bits aren't > supported. In practice, however, DQ5 is low during erase/write > operations. I am uneasy about using undocumented features. I have been thinking about the above mentioned problem with DQ5. I have not seen DQ5 behavior documented in the SST49LF040 and Pm49FL00x documentation and suspect that other chip documentation is similar. =20 Regardless of the current behavior of status bit 5 on these chips I think the documentation should be followed. This means that either the cfi_cmdset_0002 driver needs to be adapted to work with the "simplified" polling in _addition_ to the current polling of DQ5 (some switch is added to poll correctly for a given device) or a new cfi_cmdset_xxxx is written specifically for this simplified command set. I'm not sure what would be a nice, clean way to switch polling mechanisms, but I hesitate to duplicate code for a nearly identical cfi_cmdset. Thoughts? --=20 Thayne Harbaugh Linux Networx --=-S5ixrRaefhmMdHKqH2Zj Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6 (GNU/Linux) Comment: For info see http://www.gnupg.org iD8DBQA+dhYufsBPTKE6HMkRAipjAJ4iuyS+8gP8U0aVZGF6w6e8UpremgCeLWIv U/MGKz16uCV6QGXIdA6tzfQ= =SbBb -----END PGP SIGNATURE----- --=-S5ixrRaefhmMdHKqH2Zj-- ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-17 18:38 ` Thayne Harbaugh @ 2003-03-19 0:23 ` Thayne Harbaugh 2003-03-19 15:56 ` Steve Wahl 0 siblings, 1 reply; 20+ messages in thread From: Thayne Harbaugh @ 2003-03-19 0:23 UTC (permalink / raw) To: linux-mtd --=-RZKiLm5gawTslA20lq2l Content-Type: multipart/mixed; boundary="=-YdlygX9g8mw3u7YELU6q" --=-YdlygX9g8mw3u7YELU6q Content-Type: text/plain Content-Transfer-Encoding: quoted-printable On Mon, 2003-03-17 at 11:38, Thayne Harbaugh wrote: > I have been thinking about the above mentioned problem with DQ5. I have > not seen DQ5 behavior documented in the SST49LF040 and Pm49FL00x > documentation and suspect that other chip documentation is similar. I wonder if this DQ5 for non suspend/resume chips is documented in JESD21C. Does anyone know or ever have an idea where to begin digging through all the JEDEC meeting notes, etc.? > Regardless of the current behavior of status bit 5 on these chips I > think the documentation should be followed. It's just plain dangerous to follow non-documented behavior. > This means that either the > cfi_cmdset_0002 driver needs to be adapted to work with the "simplified" > polling in _addition_ to the current polling of DQ5 (some switch is > added to poll correctly for a given device) or a new cfi_cmdset_xxxx is > written specifically for this simplified command set. >=20 > I'm not sure what would be a nice, clean way to switch polling > mechanisms, but I hesitate to duplicate code for a nearly identical > cfi_cmdset. I have worked up a patch that adds a new cfi_cmdset to the mix. This is for devices that support a subset or a simplified AMD command set without the suspend/resume commands and extra query bits. I feel it's good because I don't feel comfortable trusting the behavior of DQ5 being low during erase/write operations for devices that don't support DQ5 and have undocumented behavior for bits other than DQ7 and DQ6. It throws out suspend and resume functions and polls exclusively on DQ7 and DQ6. I have called this a simplified AMD commandset (ugly name - give me something better) and have pulled cfi_cmdset_0005 out of the hat (I'm not sure how the command set numbers are chosen). Jedec devices listed in jedec_probe.c:jedec_table[] that don't support suspend resume are marked as P_ID_AMD_SIMPLIFIED (new entry in cfi.h). I'm not sure why gen_probe.c/check_cmd_set() uses the hex numbers in the switch statement rather than the P_ID_* #define's from cfi.h - I used the #define. It likely could be simplified even more - take out feeble support for interleaved chips (which I don't have and can't test and I'm not even sure that the chips that work this way support interleaving). Sometimes I wish all of the command sets shared more code - other times I'm glad they are split. Should I commit it to CVS? It works for me(TM). > Thoughts? Sorry to reply to myself - I talk back to myself as well. I still think that the current cfi_cmdset_0002.c needs a fix similar to what Steve Wahl proposed. Has that settled and will it be committed? --=20 Thayne Harbaugh Linux Networx --=-YdlygX9g8mw3u7YELU6q Content-Disposition: attachment; filename=mtd-amd_simplified.patch Content-Type: text/x-patch; name=mtd-amd_simplified.patch; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable diff -uNr mtd/drivers/mtd/chips/cfi_cmdset_0005.c mtd-amd_simplified/driver= s/mtd/chips/cfi_cmdset_0005.c --- mtd/drivers/mtd/chips/cfi_cmdset_0005.c 1969-12-31 17:00:00.000000000 -= 0700 +++ mtd-amd_simplified/drivers/mtd/chips/cfi_cmdset_0005.c 2003-03-18 16:51= :05.000000000 -0700 @@ -0,0 +1,1027 @@ +/* + * Common Flash Interface support: + * AMD Simplified command set (ID 0x0005) + * + * Copyright (C) 2000 Crossnet Co. <info@crossnet.co.jp> + * Copyright (C) 2003 Linux Networx - adapted to AMD simplified + * command set by Thayne Harbaugh. This is nearly the same + * as cfi_cmdset_0002 except for the polling mechanism for + * erase/write operations and the removal of extra + * functionality: erase suspend and resume. Ideally this and + * cfi_cmdset_0002 should share as much as possible. + * + * Although this looks like it was written for interleaved chips, + * it has never been tested. Ise at your own risk and send + * in the patches. + * + * This code is GPL + * + * $Id$ + * + */ + + +#include <linux/module.h> +#include <linux/types.h> +#include <linux/kernel.h> +#include <linux/sched.h> +#include <asm/io.h> +#include <asm/byteorder.h> + +#include <linux/errno.h> +#include <linux/slab.h> +#include <linux/delay.h> +#include <linux/interrupt.h> +#include <linux/mtd/map.h> +#include <linux/mtd/cfi.h> + + +static int cfi_amdsmpl_read (struct mtd_info *, loff_t, size_t, size_t *, = u_char *); +static int cfi_amdsmpl_write(struct mtd_info *, loff_t, size_t, size_t *, = const u_char *); +static int cfi_amdsmpl_erase_onesize(struct mtd_info *, struct erase_info = *); +static int cfi_amdsmpl_erase_varsize(struct mtd_info *, struct erase_info = *); +static void cfi_amdsmpl_sync (struct mtd_info *); +static int cfi_amdsmpl_secsi_read (struct mtd_info *, loff_t, size_t, size= _t *, u_char *); + +static void cfi_amdsmpl_destroy(struct mtd_info *); + +struct mtd_info *cfi_cmdset_0005(struct map_info *, int); +static struct mtd_info *cfi_amdsmpl_setup (struct map_info *); + + +static struct mtd_chip_driver cfi_amdsmpl_chipdrv =3D { + probe: NULL, /* Not usable directly */ + destroy: cfi_amdsmpl_destroy, + name: "cfi_cmdset_0005", + module: THIS_MODULE +}; + +struct mtd_info *cfi_cmdset_0005(struct map_info *map, int primary) +{ + struct cfi_private *cfi =3D map->fldrv_priv; + unsigned char bootloc; + int ofs_factor =3D cfi->interleave * cfi->device_type; + int i; + __u8 major, minor; + __u32 base =3D cfi->chips[0].start; + + if (cfi->cfi_mode=3D=3DCFI_MODE_CFI){ + __u16 adr =3D primary?cfi->cfiq->P_ADR:cfi->cfiq->A_ADR; + + cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); + =09 + major =3D cfi_read_query(map, base + (adr+3)*ofs_factor); + minor =3D cfi_read_query(map, base + (adr+4)*ofs_factor); + =09 + printk(KERN_NOTICE " Amd/Fujitsu Extended Query Table v%c.%c at 0x%4.4X\= n", + major, minor, adr); + cfi_send_gen_cmd(0xf0, 0x55, base, map, cfi, cfi->device_type, NULL); + =09 + cfi_send_gen_cmd(0xaa, 0x555, base, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x55, 0x2aa, base, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x90, 0x555, base, map, cfi, cfi->device_type, NULL); + cfi->mfr =3D cfi_read_query(map, base); + cfi->id =3D cfi_read_query(map, base + ofs_factor); =20 + + /* Wheee. Bring me the head of someone at AMD. */ + cfi_send_gen_cmd(0x98, 0x55, base, map, cfi, cfi->device_type, NULL); + bootloc =3D cfi_read_query(map, base + (adr+15)*ofs_factor); + if (bootloc =3D=3D 3 && cfi->cfiq->NumEraseRegions > 1) { + printk(KERN_WARNING "%s: Swapping erase regions for broken CFI table.\n= ", map->name); + =09 + for (i=3D0; i<cfi->cfiq->NumEraseRegions / 2; i++) { + int j =3D (cfi->cfiq->NumEraseRegions-1)-i; + __u32 swap; + =09 + swap =3D cfi->cfiq->EraseRegionInfo[i]; + cfi->cfiq->EraseRegionInfo[i] =3D cfi->cfiq->EraseRegionInfo[j]; + cfi->cfiq->EraseRegionInfo[j] =3D swap; + } + } + switch (cfi->device_type) { + case CFI_DEVICETYPE_X8: + cfi->addr_unlock1 =3D 0x555;=20 + cfi->addr_unlock2 =3D 0x2aa;=20 + break; + case CFI_DEVICETYPE_X16: + cfi->addr_unlock1 =3D 0xaaa; + if (map->buswidth =3D=3D cfi->interleave) { + /* X16 chip(s) in X8 mode */ + cfi->addr_unlock2 =3D 0x555; + } else { + cfi->addr_unlock2 =3D 0x554; + } + break; + case CFI_DEVICETYPE_X32: + cfi->addr_unlock1 =3D 0x1555;=20 + cfi->addr_unlock2 =3D 0xaaa;=20 + break; + default: + printk(KERN_NOTICE "Eep. Unknown cfi_cmdset_0005 device type %d\n", cfi= ->device_type); + return NULL; + } + } /* CFI mode */ + + for (i=3D0; i< cfi->numchips; i++) { + cfi->chips[i].word_write_time =3D 1<<cfi->cfiq->WordWriteTimeoutTyp; + cfi->chips[i].buffer_write_time =3D 1<<cfi->cfiq->BufWriteTimeoutTyp; + cfi->chips[i].erase_time =3D 1<<cfi->cfiq->BlockEraseTimeoutTyp; + } =09 +=09 + map->fldrv =3D &cfi_amdsmpl_chipdrv; + + cfi_send_gen_cmd(0xf0, 0x55, base, map, cfi, cfi->device_type, NULL); + return cfi_amdsmpl_setup(map); +} + +static struct mtd_info *cfi_amdsmpl_setup(struct map_info *map) +{ + struct cfi_private *cfi =3D map->fldrv_priv; + struct mtd_info *mtd; + unsigned long devsize =3D (1<<cfi->cfiq->DevSize) * cfi->interleave; + + mtd =3D kmalloc(sizeof(*mtd), GFP_KERNEL); + printk(KERN_NOTICE "number of %s chips: %d\n",=20 + (cfi->cfi_mode =3D=3D CFI_MODE_CFI)?"CFI":"JEDEC",cfi->numchips); + + if (!mtd) { + printk(KERN_WARNING "Failed to allocate memory for MTD device\n"); + goto setup_err; + } + + memset(mtd, 0, sizeof(*mtd)); + mtd->priv =3D map; + mtd->type =3D MTD_NORFLASH; + /* Also select the correct geometry setup too */=20 + mtd->size =3D devsize * cfi->numchips; +=09 + if (cfi->cfiq->NumEraseRegions =3D=3D 1) { + /* No need to muck about with multiple erase sizes */ + mtd->erasesize =3D ((cfi->cfiq->EraseRegionInfo[0] >> 8) & ~0xff) * cfi-= >interleave; + } else { + unsigned long offset =3D 0; + int i,j; + + mtd->numeraseregions =3D cfi->cfiq->NumEraseRegions * cfi->numchips; + mtd->eraseregions =3D kmalloc(sizeof(struct mtd_erase_region_info) * mtd= ->numeraseregions, GFP_KERNEL); + if (!mtd->eraseregions) {=20 + printk(KERN_WARNING "Failed to allocate memory for MTD erase region inf= o\n"); + goto setup_err; + } + =09 + for (i=3D0; i<cfi->cfiq->NumEraseRegions; i++) { + unsigned long ernum, ersize; + ersize =3D ((cfi->cfiq->EraseRegionInfo[i] >> 8) & ~0xff) * cfi->interl= eave; + ernum =3D (cfi->cfiq->EraseRegionInfo[i] & 0xffff) + 1; + =09 + if (mtd->erasesize < ersize) { + mtd->erasesize =3D ersize; + } + for (j=3D0; j<cfi->numchips; j++) { + mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].offset =3D (j*devs= ize)+offset; + mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize =3D ersi= ze; + mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks =3D ernu= m; + } + offset +=3D (ersize * ernum); + } + if (offset !=3D devsize) { + /* Argh */ + printk(KERN_WARNING "Sum of regions (%lx) !=3D total size of set of int= erleaved chips (%lx)\n", offset, devsize); + goto setup_err; + } +#if 0 + // debug + for (i=3D0; i<mtd->numeraseregions;i++){ + printk("%d: offset=3D0x%x,size=3D0x%x,blocks=3D%d\n", + i,mtd->eraseregions[i].offset, + mtd->eraseregions[i].erasesize, + mtd->eraseregions[i].numblocks); + } +#endif + } + + switch (CFIDEV_BUSWIDTH) + { + case 1: + case 2: + case 4: +#if 1 + if (mtd->numeraseregions > 1) + mtd->erase =3D cfi_amdsmpl_erase_varsize; + else +#endif + mtd->erase =3D cfi_amdsmpl_erase_onesize; + mtd->read =3D cfi_amdsmpl_read; + mtd->write =3D cfi_amdsmpl_write; + break; + + default: + printk(KERN_WARNING "Unsupported buswidth\n"); + goto setup_err; + break; + } + if (cfi->fast_prog) { + /* In cfi_amdsmpl_write() we frob the protection stuff + without paying any attention to the state machine. + This upsets in-progress erases. So we turn this flag + off for now till the code gets fixed. */ + printk(KERN_NOTICE "cfi_cmdset_0005: Disabling fast programming due to c= ode brokenness.\n"); + cfi->fast_prog =3D 0; + } + + + /* does this chip have a secsi area? */ + if(cfi->mfr=3D=3D1){ + =09 + switch(cfi->id){ + case 0x50: + case 0x53: + case 0x55: + case 0x56: + case 0x5C: + case 0x5F: + /* Yes */ + mtd->read_user_prot_reg =3D cfi_amdsmpl_secsi_read; + mtd->read_fact_prot_reg =3D cfi_amdsmpl_secsi_read; + default: =20 + ; + } + } +=09 + =09 + mtd->sync =3D cfi_amdsmpl_sync; + mtd->suspend =3D NULL; + mtd->resume =3D NULL; + mtd->flags =3D MTD_CAP_NORFLASH; + map->fldrv =3D &cfi_amdsmpl_chipdrv; + mtd->name =3D map->name; + MOD_INC_USE_COUNT; + return mtd; + + setup_err: + if(mtd) { + if(mtd->eraseregions) + kfree(mtd->eraseregions); + kfree(mtd); + } + kfree(cfi->cmdset_priv); + kfree(cfi->cfiq); + return NULL; +} + +static inline int do_read_onechip(struct map_info *map, struct flchip *chi= p, loff_t adr, size_t len, u_char *buf) +{ + DECLARE_WAITQUEUE(wait, current); + unsigned long timeo =3D jiffies + HZ; + + retry: + cfi_spin_lock(chip->mutex); + + if (chip->state !=3D FL_READY){ +#if 0 + printk(KERN_DEBUG "Waiting for chip to read, status =3D %d\n", ch= ip->state); +#endif + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&chip->wq, &wait); + =20 + cfi_spin_unlock(chip->mutex); + + schedule(); + remove_wait_queue(&chip->wq, &wait); +#if 0 + if(signal_pending(current)) + return -EINTR; +#endif + timeo =3D jiffies + HZ; + + goto retry; + }=09 + + adr +=3D chip->start; + + chip->state =3D FL_READY; + + map->copy_from(map, buf, adr, len); + + wake_up(&chip->wq); + cfi_spin_unlock(chip->mutex); + + return 0; +} + +static int cfi_amdsmpl_read (struct mtd_info *mtd, loff_t from, size_t len= , size_t *retlen, u_char *buf) +{ + struct map_info *map =3D mtd->priv; + struct cfi_private *cfi =3D map->fldrv_priv; + unsigned long ofs; + int chipnum; + int ret =3D 0; + + /* ofs: offset within the first chip that the first read should start */ + + chipnum =3D (from >> cfi->chipshift); + ofs =3D from - (chipnum << cfi->chipshift); + + + *retlen =3D 0; + + while (len) { + unsigned long thislen; + + if (chipnum >=3D cfi->numchips) + break; + + if ((len + ofs -1) >> cfi->chipshift) + thislen =3D (1<<cfi->chipshift) - ofs; + else + thislen =3D len; + + ret =3D do_read_onechip(map, &cfi->chips[chipnum], ofs, thislen, buf); + if (ret) + break; + + *retlen +=3D thislen; + len -=3D thislen; + buf +=3D thislen; + + ofs =3D 0; + chipnum++; + } + return ret; +} + +static inline int do_read_secsi_onechip(struct map_info *map, struct flchi= p *chip, loff_t adr, size_t len, u_char *buf) +{ + DECLARE_WAITQUEUE(wait, current); + unsigned long timeo =3D jiffies + HZ; + struct cfi_private *cfi =3D map->fldrv_priv; + + retry: + cfi_spin_lock(chip->mutex); + + if (chip->state !=3D FL_READY){ +#if 0 + printk(KERN_DEBUG "Waiting for chip to read, status =3D %d\n", ch= ip->state); +#endif + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&chip->wq, &wait); + =20 + cfi_spin_unlock(chip->mutex); + + schedule(); + remove_wait_queue(&chip->wq, &wait); +#if 0 + if(signal_pending(current)) + return -EINTR; +#endif + timeo =3D jiffies + HZ; + + goto retry; + }=09 + + adr +=3D chip->start; + + chip->state =3D FL_READY; +=09 + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->dev= ice_type, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->dev= ice_type, NULL); + cfi_send_gen_cmd(0x88, cfi->addr_unlock1, chip->start, map, cfi, cfi->dev= ice_type, NULL); +=09 + map->copy_from(map, buf, adr, len); + + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->dev= ice_type, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->dev= ice_type, NULL); + cfi_send_gen_cmd(0x90, cfi->addr_unlock1, chip->start, map, cfi, cfi->dev= ice_type, NULL); + cfi_send_gen_cmd(0x00, cfi->addr_unlock1, chip->start, map, cfi, cfi->dev= ice_type, NULL); +=09 + wake_up(&chip->wq); + cfi_spin_unlock(chip->mutex); + + return 0; +} + +static int cfi_amdsmpl_secsi_read (struct mtd_info *mtd, loff_t from, size= _t len, size_t *retlen, u_char *buf) +{ + struct map_info *map =3D mtd->priv; + struct cfi_private *cfi =3D map->fldrv_priv; + unsigned long ofs; + int chipnum; + int ret =3D 0; + + + /* ofs: offset within the first chip that the first read should start */ + + /* 8 secsi bytes per chip */ + chipnum=3Dfrom>>3; + ofs=3Dfrom & 7; + + + *retlen =3D 0; + + while (len) { + unsigned long thislen; + + if (chipnum >=3D cfi->numchips) + break; + + if ((len + ofs -1) >> 3) + thislen =3D (1<<3) - ofs; + else + thislen =3D len; + + ret =3D do_read_secsi_onechip(map, &cfi->chips[chipnum], ofs, thislen, b= uf); + if (ret) + break; + + *retlen +=3D thislen; + len -=3D thislen; + buf +=3D thislen; + + ofs =3D 0; + chipnum++; + } + return ret; +} + + +static inline int status_poll( struct map_info *map, struct flchip *chip, = unsigned long adr, __u32 datum, unsigned long timeo ) +{ + int ret =3D 0; + unsigned int dq6, dq7;=09 + unsigned int oldstatus, status; + struct cfi_private *cfi =3D map->fldrv_priv; + + /* + * Wait for the end of programing/erasure by using the toggle method. + * As long as there is a programming procedure going on, bit 6 of the las= t + * written byte is toggling it's state with each consectuve read and + * bit 7 is the complement of the data written. + * The toggling stops as soon as the procedure is completed and bit + * 7 represents true data. + */ + + /* + * Polling toggle bits instead of reading back many times + * This ensures that write operation is really completed, + */ + dq6 =3D CMD(1<<6); /* toggle until operation finishes */ + dq7 =3D CMD(1<<7); /* inverts data until operation finishes */ + + oldstatus =3D cfi_read(map, adr); + status =3D cfi_read(map, adr); + DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.2x 0x%.2x\n", __func__, old= status, status ); + + while( ( ( oldstatus ^ status ) & dq6 ) + && ( ( status ^ datum ) & dq7 ) + && ! time_after(jiffies, timeo) ) { + + if (need_resched()) { + cfi_spin_unlock(chip->mutex); + yield(); + cfi_spin_lock(chip->mutex); + } else=20 + udelay(1); + + oldstatus =3D cfi_read( map, adr ); + status =3D cfi_read( map, adr ); + DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): Check 0x%.2x 0x%.2x\n", __func__, ol= dstatus, status ); + } + + if ( time_after( jiffies, timeo ) ) { + /* + * The operation did not complete in reasonable time - the + * chip should be reset. + */ + printk(KERN_WARNING + "MTD %s(): Internal flash device timeout occured\n", + __func__ ); + cfi_write( map, CMD(0xF0), chip->start ); + ret =3D -EIO; + } else { + + status =3D cfi_read(map, adr); + + if ( datum !=3D status ) { + /* must check two more times and succeed for both */ + oldstatus =3D cfi_read(map, adr); + status =3D cfi_read(map, adr); + if ( datum !=3D oldstatus || datum !=3D status ) { + DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): 0x%.2x !=3D 0x%.2x\n", __func__, s= tatus, datum ); + ret =3D -EIO; + } + } + } + + return ret; +} + + +static int do_write_oneword(struct map_info *map, struct flchip *chip, uns= igned long adr, __u32 datum, int fast) +{ + unsigned long timeo =3D jiffies + HZ; + struct cfi_private *cfi =3D map->fldrv_priv; + /* We use a 1ms + 1 jiffies generic timeout for writes (most devices h= ave + a max write time of a few hundreds usec). However, we should use th= e + maximum timeout value given by the chip at probe time instead.=20 + Unfortunately, struct flchip does have a field for maximum timeout,= =20 + only for typical which can be far too short depending of the condit= ions. + The ' + 1' is to avoid having a timeout of 0 jiffies if HZ is small= er + than 1000. Using a static variable allows makes us save the costly + divide operation at each word write.*/=20 + static unsigned long uWriteTimeout =3D ( HZ / 1000 ) + 1; + DECLARE_WAITQUEUE(wait, current); + int ret =3D 0; + + retry: + cfi_spin_lock(chip->mutex); + + if (chip->state !=3D FL_READY) { +#if 0 + printk(KERN_DEBUG "Waiting for chip to write, status =3D %d\n", c= hip->state); +#endif + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&chip->wq, &wait); + =20 + cfi_spin_unlock(chip->mutex); + + schedule(); + remove_wait_queue(&chip->wq, &wait); +#if 0 + printk(KERN_DEBUG "Wake up to write:\n"); + if(signal_pending(current)) + return -EINTR; +#endif + timeo =3D jiffies + HZ; + + goto retry; + }=09 + + chip->state =3D FL_WRITING; + + DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): WRITE (0x%.8lx)0x%.2x\n", __func__, a= dr, datum ); + adr +=3D chip->start; + ENABLE_VPP(map); + if (fast) { /* Unlock bypass */ + cfi_send_gen_cmd(0xA0, 0, chip->start, map, cfi, cfi->device_type, NULL)= ; + } + else { + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, = CFI_DEVICETYPE_X8, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, = CFI_DEVICETYPE_X8, NULL); + cfi_send_gen_cmd(0xA0, cfi->addr_unlock1, chip->start, map, cfi, = CFI_DEVICETYPE_X8, NULL); + } + + cfi_write(map, datum, adr); + + cfi_spin_unlock(chip->mutex); + cfi_udelay(chip->word_write_time); + cfi_spin_lock(chip->mutex); + + /* See comment above for timeout value. */ + ret =3D status_poll( map, chip, adr, datum, jiffies + uWriteTimeout ); + + DISABLE_VPP(map); + chip->state =3D FL_READY; + wake_up(&chip->wq); + cfi_spin_unlock(chip->mutex); + + return ret; +} + + +static int cfi_amdsmpl_write (struct mtd_info *mtd, loff_t to , size_t len= , size_t *retlen, const u_char *buf) +{ + struct map_info *map =3D mtd->priv; + struct cfi_private *cfi =3D map->fldrv_priv; + int ret =3D 0; + int chipnum; + unsigned long ofs, chipstart; + + *retlen =3D 0; + if (!len) + return 0; + + chipnum =3D to >> cfi->chipshift; + ofs =3D to - (chipnum << cfi->chipshift); + chipstart =3D cfi->chips[chipnum].start; + + /* If it's not bus-aligned, do the first byte write */ + if (ofs & (CFIDEV_BUSWIDTH-1)) { + unsigned long bus_ofs =3D ofs & ~(CFIDEV_BUSWIDTH-1); + int i =3D ofs - bus_ofs; + int n =3D 0; + u_char tmp_buf[8]; + __u32 datum; + + map->copy_from(map, tmp_buf, bus_ofs + cfi->chips[chipnum].start, CFIDEV= _BUSWIDTH); + while (len && i < CFIDEV_BUSWIDTH) + tmp_buf[i++] =3D buf[n++], len--; + + if (cfi_buswidth_is_2()) { + datum =3D *(__u16*)tmp_buf; + } else if (cfi_buswidth_is_4()) { + datum =3D *(__u32*)tmp_buf; + } else { + return -EINVAL; /* should never happen, but be safe */ + } + + ret =3D do_write_oneword(map, &cfi->chips[chipnum],=20 + bus_ofs, datum, 0); + if (ret)=20 + return ret; + =09 + ofs +=3D n; + buf +=3D n; + (*retlen) +=3D n; + + if (ofs >> cfi->chipshift) { + chipnum ++;=20 + ofs =3D 0; + if (chipnum =3D=3D cfi->numchips) + return 0; + } + } +=09 + if (cfi->fast_prog) { + /* Go into unlock bypass mode */ + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVIC= ETYPE_X8, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi, CFI_DEVIC= ETYPE_X8, NULL); + cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEVIC= ETYPE_X8, NULL); + } + + /* We are now aligned, write as much as possible */ + while(len >=3D CFIDEV_BUSWIDTH) { + __u32 datum; + + if (cfi_buswidth_is_1()) { + datum =3D *(__u8*)buf; + } else if (cfi_buswidth_is_2()) { + datum =3D *(__u16*)buf; + } else if (cfi_buswidth_is_4()) { + datum =3D *(__u32*)buf; + } else { + return -EINVAL; + } + ret =3D do_write_oneword(map, &cfi->chips[chipnum], + ofs, datum, cfi->fast_prog); + if (ret) { + if (cfi->fast_prog){ + /* Get out of unlock bypass mode */ + cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi, cfi->device_type, NULL)= ; + cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi, cfi->device_type, NULL)= ; + } + return ret; + } + + ofs +=3D CFIDEV_BUSWIDTH; + buf +=3D CFIDEV_BUSWIDTH; + (*retlen) +=3D CFIDEV_BUSWIDTH; + len -=3D CFIDEV_BUSWIDTH; + + if (ofs >> cfi->chipshift) { + if (cfi->fast_prog){ + /* Get out of unlock bypass mode */ + cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi, cfi->device_type, NULL)= ; + cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi, cfi->device_type, NULL)= ; + } + + chipnum ++;=20 + ofs =3D 0; + if (chipnum =3D=3D cfi->numchips) + return 0; + chipstart =3D cfi->chips[chipnum].start; + if (cfi->fast_prog){ + /* Go into unlock bypass mode for next set of chips */ + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEV= ICETYPE_X8, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chipstart, map, cfi, CFI_DEV= ICETYPE_X8, NULL); + cfi_send_gen_cmd(0x20, cfi->addr_unlock1, chipstart, map, cfi, CFI_DEV= ICETYPE_X8, NULL); + } + } + } + + if (cfi->fast_prog){ + /* Get out of unlock bypass mode */ + cfi_send_gen_cmd(0x90, 0, chipstart, map, cfi, cfi->device_type, NULL); + cfi_send_gen_cmd(0x00, 0, chipstart, map, cfi, cfi->device_type, NULL); + } + + /* Write the trailing bytes if any */ + if (len & (CFIDEV_BUSWIDTH-1)) { + int i =3D 0, n =3D 0; + u_char tmp_buf[8]; + __u32 datum; + + map->copy_from(map, tmp_buf, ofs + cfi->chips[chipnum].start, CFIDEV_BUS= WIDTH); + while (len--) + tmp_buf[i++] =3D buf[n++]; + + if (cfi_buswidth_is_2()) { + datum =3D *(__u16*)tmp_buf; + } else if (cfi_buswidth_is_4()) { + datum =3D *(__u32*)tmp_buf; + } else { + return -EINVAL; /* should never happen, but be safe */ + } + + ret =3D do_write_oneword(map, &cfi->chips[chipnum],=20 + ofs, datum, 0); + if (ret)=20 + return ret; + =09 + (*retlen) +=3D n; + } + + return 0; +} + + +static inline int do_erase_oneblock(struct map_info *map, struct flchip *c= hip, unsigned long adr) +{ + int ret =3D 0; + unsigned long timeo =3D jiffies + HZ; + struct cfi_private *cfi =3D map->fldrv_priv; + DECLARE_WAITQUEUE(wait, current); + __u32 ones =3D 0; + + retry: + cfi_spin_lock(chip->mutex); + + if (chip->state !=3D FL_READY){ + set_current_state(TASK_UNINTERRUPTIBLE); + add_wait_queue(&chip->wq, &wait); + =20 + cfi_spin_unlock(chip->mutex); + + schedule(); + remove_wait_queue(&chip->wq, &wait); +#if 0 + if(signal_pending(current)) + return -EINTR; +#endif + timeo =3D jiffies + HZ; + + goto retry; + }=09 + + chip->state =3D FL_ERASING; + + DEBUG( MTD_DEBUG_LEVEL3, "MTD %s(): ERASE 0x%.8lx\n", __func__, adr ); + adr +=3D chip->start; + ENABLE_VPP(map); + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVI= CETYPE_X8, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVI= CETYPE_X8, NULL); + cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVI= CETYPE_X8, NULL); + cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, CFI_DEVI= CETYPE_X8, NULL); + cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, CFI_DEVI= CETYPE_X8, NULL); + cfi_write(map, CMD(0x30), adr); + + switch( CFIDEV_BUSWIDTH ) { + case 1: + ones =3D (__u8)~0; + break; + case 2: + ones =3D (__u16)~0; + break; + case 4: + ones =3D (__u32)~0; + break; + } +=09 + ret =3D status_poll( map, chip, adr, ones, jiffies + (HZ*20) ); + + DISABLE_VPP(map); + chip->state =3D FL_READY; + wake_up(&chip->wq); + cfi_spin_unlock(chip->mutex); + return ret; +} + + +static int cfi_amdsmpl_erase_varsize(struct mtd_info *mtd, struct erase_in= fo *instr) +{ + struct map_info *map =3D mtd->priv; + struct cfi_private *cfi =3D map->fldrv_priv; + unsigned long adr, len; + int chipnum, ret =3D 0; + int i, first; + struct mtd_erase_region_info *regions =3D mtd->eraseregions; + + if (instr->addr > mtd->size) + return -EINVAL; + + if ((instr->len + instr->addr) > mtd->size) + return -EINVAL; + + /* Check that both start and end of the requested erase are + * aligned with the erasesize at the appropriate addresses. + */ + + i =3D 0; + + /* Skip all erase regions which are ended before the start of=20 + the requested erase. Actually, to save on the calculations, + we skip to the first erase region which starts after the + start of the requested erase, and then go back one. + */ +=09 + while (i < mtd->numeraseregions && instr->addr >=3D regions[i].offset) + i++; + i--; + + /* OK, now i is pointing at the erase region in which this=20 + erase request starts. Check the start of the requested + erase range is aligned with the erase size which is in + effect here. + */ + + if (instr->addr & (regions[i].erasesize-1)) + return -EINVAL; + + /* Remember the erase region we start on */ + first =3D i; + + /* Next, check that the end of the requested erase is aligned + * with the erase region at that address. + */ + + while (i<mtd->numeraseregions && (instr->addr + instr->len) >=3D regions[= i].offset) + i++; + + /* As before, drop back one to point at the region in which + the address actually falls + */ + i--; +=09 + if ((instr->addr + instr->len) & (regions[i].erasesize-1)) + return -EINVAL; +=09 + chipnum =3D instr->addr >> cfi->chipshift; + adr =3D instr->addr - (chipnum << cfi->chipshift); + len =3D instr->len; + + i=3Dfirst; + + while(len) { + ret =3D do_erase_oneblock(map, &cfi->chips[chipnum], adr); + + if (ret) + return ret; + + adr +=3D regions[i].erasesize; + len -=3D regions[i].erasesize; + + if (adr % (1<< cfi->chipshift) =3D=3D ((regions[i].offset + (regions[i].= erasesize * regions[i].numblocks)) %( 1<< cfi->chipshift))) + i++; + + if (adr >> cfi->chipshift) { + adr =3D 0; + chipnum++; + =09 + if (chipnum >=3D cfi->numchips) + break; + } + } + + instr->state =3D MTD_ERASE_DONE; + if (instr->callback) + instr->callback(instr); +=09 + return 0; +} + + +static int cfi_amdsmpl_erase_onesize(struct mtd_info *mtd, struct erase_in= fo *instr) +{ + struct map_info *map =3D mtd->priv; + struct cfi_private *cfi =3D map->fldrv_priv; + unsigned long adr, len; + int chipnum, ret =3D 0; + + if (instr->addr & (mtd->erasesize - 1)) + return -EINVAL; + + if (instr->len & (mtd->erasesize -1)) + return -EINVAL; + + if ((instr->len + instr->addr) > mtd->size) + return -EINVAL; + + chipnum =3D instr->addr >> cfi->chipshift; + adr =3D instr->addr - (chipnum << cfi->chipshift); + len =3D instr->len; + + while(len) { + ret =3D do_erase_oneblock(map, &cfi->chips[chipnum], adr); + + if (ret) + return ret; + + adr +=3D mtd->erasesize; + len -=3D mtd->erasesize; + + if (adr >> cfi->chipshift) { + adr =3D 0; + chipnum++; + =09 + if (chipnum >=3D cfi->numchips) + break; + } + } + =09 + instr->state =3D MTD_ERASE_DONE; + if (instr->callback) + instr->callback(instr); +=09 + return 0; +} + + +static void cfi_amdsmpl_sync (struct mtd_info *mtd) +{ + struct map_info *map =3D mtd->priv; + struct cfi_private *cfi =3D map->fldrv_priv; + int i; + struct flchip *chip; + int ret =3D 0; + DECLARE_WAITQUEUE(wait, current); + + for (i=3D0; !ret && i<cfi->numchips; i++) { + chip =3D &cfi->chips[i]; + + retry: + cfi_spin_lock(chip->mutex); + + switch(chip->state) { + case FL_READY: + case FL_STATUS: + case FL_CFI_QUERY: + case FL_JEDEC_QUERY: + chip->oldstate =3D chip->state; + chip->state =3D FL_SYNCING; + /* No need to wake_up() on this state change -=20 + * as the whole point is that nobody can do anything + * with the chip now anyway. + */ + case FL_SYNCING: + cfi_spin_unlock(chip->mutex); + break; + + default: + /* Not an idle state */ + add_wait_queue(&chip->wq, &wait); + =09 + cfi_spin_unlock(chip->mutex); + + schedule(); + + remove_wait_queue(&chip->wq, &wait); + =09 + goto retry; + } + } + + /* Unlock the chips again */ + + for (i--; i >=3D0; i--) { + chip =3D &cfi->chips[i]; + + cfi_spin_lock(chip->mutex); + =09 + if (chip->state =3D=3D FL_SYNCING) { + chip->state =3D chip->oldstate; + wake_up(&chip->wq); + } + cfi_spin_unlock(chip->mutex); + } +} + + +static void cfi_amdsmpl_destroy(struct mtd_info *mtd) +{ + struct map_info *map =3D mtd->priv; + struct cfi_private *cfi =3D map->fldrv_priv; + kfree(cfi->cmdset_priv); + kfree(cfi->cfiq); + kfree(cfi); + kfree(mtd->eraseregions); +} + +static char im_name[]=3D"cfi_cmdset_0005"; + +int __init cfi_amdsmpl_init(void) +{ + inter_module_register(im_name, THIS_MODULE, &cfi_cmdset_0005); + return 0; +} + +static void __exit cfi_amdsmpl_exit(void) +{ + inter_module_unregister(im_name); +} + +module_init(cfi_amdsmpl_init); +module_exit(cfi_amdsmpl_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Linux Networx - based on cfi_cmdset_0002.c by Crossnet Co. = et al."); +MODULE_DESCRIPTION("MTD chip driver for AMD/Fujitsu simplified flash chips= "); + diff -uNr mtd/drivers/mtd/chips/Config.in mtd-amd_simplified/drivers/mtd/ch= ips/Config.in --- mtd/drivers/mtd/chips/Config.in 2002-09-03 07:30:43.000000000 -0600 +++ mtd-amd_simplified/drivers/mtd/chips/Config.in 2003-03-18 16:51:05.0000= 00000 -0700 @@ -44,6 +44,7 @@ fi dep_tristate ' Support for Intel/Sharp flash chips' CONFIG_MTD_CFI_INTELE= XT $CONFIG_MTD_GEN_PROBE dep_tristate ' Support for AMD/Fujitsu flash chips' CONFIG_MTD_CFI_AMDSTD= $CONFIG_MTD_GEN_PROBE +dep_tristate ' Support for AMD Simplified flash chips' CONFIG_MTD_AMDSIMP= LIFIED $CONFIG_MTD_GEN_PROBE dep_tristate ' Support for ST (Advanced Architecture) flash chips' CONFIG= _MTD_CFI_STAA $CONFIG_MTD_GEN_PROBE =20 dep_tristate ' Support for RAM chips in bus mapping' CONFIG_MTD_RAM $CONF= IG_MTD diff -uNr mtd/drivers/mtd/chips/gen_probe.c mtd-amd_simplified/drivers/mtd/= chips/gen_probe.c --- mtd/drivers/mtd/chips/gen_probe.c 2003-01-31 06:35:07.000000000 -0700 +++ mtd-amd_simplified/drivers/mtd/chips/gen_probe.c 2003-03-18 16:51:05.00= 0000000 -0700 @@ -331,6 +331,10 @@ case 0x0002: return cfi_cmdset_0002(map, primary); #endif +#ifdef CONFIG_MTD_CFI_AMDSMPLFD + case P_ID_AMD_SIMPLIFIED: + return cfi_cmdset_0005(map, primary); +#endif #ifdef CONFIG_MTD_CFI_STAA case 0x0020: return cfi_cmdset_0020(map, primary); diff -uNr mtd/drivers/mtd/chips/jedec_probe.c mtd-amd_simplified/drivers/mt= d/chips/jedec_probe.c --- mtd/drivers/mtd/chips/jedec_probe.c 2003-03-18 16:36:28.000000000 -0700 +++ mtd-amd_simplified/drivers/mtd/chips/jedec_probe.c 2003-03-18 16:51:05.= 000000000 -0700 @@ -746,7 +746,7 @@ name: "Atmel AT49BV512", uaddr: MTD_UADDR_0x5555_0x2AAA, DevSize: SIZE_64KiB, - CmdSet: P_ID_AMD_STD, + CmdSet: P_ID_AMD_SIMPLIFIED, NumEraseRegions: 1, regions: {ERASEINFO(0x10000,1) } @@ -756,7 +756,7 @@ name: "Atmel AT29LV512", uaddr: MTD_UADDR_0x5555_0x2AAA, DevSize: SIZE_64KiB, - CmdSet: P_ID_AMD_STD, + CmdSet: P_ID_AMD_SIMPLIFIED, NumEraseRegions: 1, regions: { ERASEINFO(0x80,256), @@ -934,7 +934,7 @@ name: "SST 39LF512", uaddr: MTD_UADDR_0x5555_0x2AAA, DevSize: SIZE_64KiB, - CmdSet: P_ID_AMD_STD, + CmdSet: P_ID_AMD_SIMPLIFIED, NumEraseRegions: 1, regions: {ERASEINFO(0x01000,16), } @@ -944,7 +944,7 @@ name: "SST 39LF010", uaddr: MTD_UADDR_0x5555_0x2AAA, DevSize: SIZE_128KiB, - CmdSet: P_ID_AMD_STD, + CmdSet: P_ID_AMD_SIMPLIFIED, NumEraseRegions: 1, regions: {ERASEINFO(0x01000,32), } @@ -954,7 +954,7 @@ name: "SST 39LF020", uaddr: MTD_UADDR_0x5555_0x2AAA, DevSize: SIZE_256KiB, - CmdSet: P_ID_AMD_STD, + CmdSet: P_ID_AMD_SIMPLIFIED, NumEraseRegions: 1, regions: {ERASEINFO(0x01000,64), } @@ -964,7 +964,7 @@ name: "SST 39LF040", uaddr: MTD_UADDR_0x5555_0x2AAA, DevSize: SIZE_512KiB, - CmdSet: P_ID_AMD_STD, + CmdSet: P_ID_AMD_SIMPLIFIED, NumEraseRegions: 1, regions: {ERASEINFO(0x01000,128), } @@ -974,7 +974,7 @@ name: "SST 39SF010A", uaddr: MTD_UADDR_0x5555_0x2AAA, DevSize: SIZE_128KiB, - CmdSet: P_ID_AMD_STD, + CmdSet: P_ID_AMD_SIMPLIFIED, NumEraseRegions: 1, regions: {ERASEINFO(0x01000,32), } @@ -984,7 +984,7 @@ name: "SST 39SF020A", uaddr: MTD_UADDR_0x5555_0x2AAA, DevSize: SIZE_256KiB, - CmdSet: P_ID_AMD_STD, + CmdSet: P_ID_AMD_SIMPLIFIED, NumEraseRegions: 1, regions: {ERASEINFO(0x01000,64), } @@ -994,7 +994,7 @@ name: "SST 49LF030A", uaddr: MTD_UADDR_0x5555_0x2AAA, DevSize: SIZE_512KiB, - CmdSet: P_ID_AMD_STD, + CmdSet: P_ID_AMD_SIMPLIFIED, NumEraseRegions: 1, regions: {ERASEINFO(0x01000,96), } @@ -1004,7 +1004,7 @@ name: "SST 49LF040A", uaddr: MTD_UADDR_0x5555_0x2AAA, DevSize: SIZE_512KiB, - CmdSet: P_ID_AMD_STD, + CmdSet: P_ID_AMD_SIMPLIFIED, NumEraseRegions: 1, regions: {ERASEINFO(0x01000,128), } @@ -1014,7 +1014,7 @@ name: "SST 49LF080A", uaddr: MTD_UADDR_0x5555_0x2AAA, DevSize: SIZE_1MiB, - CmdSet: P_ID_AMD_STD, + CmdSet: P_ID_AMD_SIMPLIFIED, NumEraseRegions: 1, regions: {ERASEINFO(0x01000,256), } @@ -1024,7 +1024,7 @@ name: "PMC_Pm49FL002", uaddr: MTD_UADDR_0x5555_0x2AAA, DevSize: SIZE_256KiB, - CmdSet: P_ID_AMD_STD, + CmdSet: P_ID_AMD_SIMPLIFIED, NumEraseRegions: 1, regions: { ERASEINFO( 0x01000, 64 ) @@ -1035,7 +1035,7 @@ name: "PMC_Pm49FL004", uaddr: MTD_UADDR_0x5555_0x2AAA, DevSize: SIZE_512KiB, - CmdSet: P_ID_AMD_STD, + CmdSet: P_ID_AMD_SIMPLIFIED, NumEraseRegions: 1, regions: { ERASEINFO( 0x01000, 128 ) @@ -1046,7 +1046,7 @@ name: "PMC_Pm49FL008", uaddr: MTD_UADDR_0x5555_0x2AAA, DevSize: SIZE_1MiB, - CmdSet: P_ID_AMD_STD, + CmdSet: P_ID_AMD_SIMPLIFIED, NumEraseRegions: 1, regions: { ERASEINFO( 0x01000, 256 ) diff -uNr mtd/drivers/mtd/chips/Makefile mtd-amd_simplified/drivers/mtd/chi= ps/Makefile --- mtd/drivers/mtd/chips/Makefile 2003-02-13 14:07:31.000000000 -0700 +++ mtd-amd_simplified/drivers/mtd/chips/Makefile 2003-03-18 16:51:05.00000= 0000 -0700 @@ -22,6 +22,7 @@ obj-$(CONFIG_MTD_AMDSTD) +=3D amd_flash.o=20 obj-$(CONFIG_MTD_CFI) +=3D cfi_probe.o obj-$(CONFIG_MTD_CFI_STAA) +=3D cfi_cmdset_0020.o +obj-$(CONFIG_MTD_AMDSIMPLIFIED) +=3D cfi_cmdset_0005.o obj-$(CONFIG_MTD_CFI_AMDSTD) +=3D cfi_cmdset_0002.o obj-$(CONFIG_MTD_CFI_INTELEXT) +=3D cfi_cmdset_0001.o obj-$(CONFIG_MTD_GEN_PROBE) +=3D gen_probe.o diff -uNr mtd/patches/Configure.help mtd-amd_simplified/patches/Configure.h= elp --- mtd/patches/Configure.help 2002-11-26 17:24:38.000000000 -0700 +++ mtd-amd_simplified/patches/Configure.help 2003-03-18 16:49:13.000000000= -0700 @@ -295,6 +295,20 @@ =20 It also works on AMD compatible chips that do conform to CFI. =20 +AMD simplified compatible flash chip support (non-CFI) +CONFIG_MTD_AMDSIMPLIFIED + This option enables support for flash chips using a subset of + AMD commands. These devices provide toggle and complement status + polling bits but do not have support for other status bits and the + more sophisticated functions, such as erase suspend, that those + chips support. + + This driver is also available as a module ( =3D code which can be + inserted in and removed from the running kernel whenever you want). + If you want to compile it as a module, say M here and read + <file:Documentation/modules.txt>. The module will be called + amd_flash.o + Support for RAM chips in bus mapping CONFIG_MTD_RAM This option enables basic support for RAM chips accessed through=20 --=-YdlygX9g8mw3u7YELU6q-- --=-RZKiLm5gawTslA20lq2l Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6 (GNU/Linux) Comment: For info see http://www.gnupg.org iD8DBQA+d7iPfsBPTKE6HMkRAkwTAJ4vev0OXxtA+UDKkQEcq5sTJegPXQCeMDXw /yRF12JriuOF4pSLMwLjhpw= =cYZW -----END PGP SIGNATURE----- --=-RZKiLm5gawTslA20lq2l-- ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-19 0:23 ` Thayne Harbaugh @ 2003-03-19 15:56 ` Steve Wahl 2003-03-19 19:38 ` Thayne Harbaugh 0 siblings, 1 reply; 20+ messages in thread From: Steve Wahl @ 2003-03-19 15:56 UTC (permalink / raw) To: linux-mtd On Tue, Mar 18, 2003 at 05:23:43PM -0700, Thayne Harbaugh wrote: > It likely could be simplified even more - take out feeble support for > interleaved chips (which I don't have and can't test and I'm not even > sure that the chips that work this way support interleaving). Interleaved operation is probably always supported, because the chips don't "know" they're doing it. Unless I'm completely mistaken, interleaving is simply having N chips with a data bus width of W on a bus that's N * W wide. For instance, I once worked on a product with a processor that didn't do anything smaller than a 32 bit bus, so the flash area of memory was populated with 4 chips (each 8 bits wide). For these, you generally issue the commands to all chips at one time, in this case writing 32 bit words with the command bytes replicated in each byte of the word. Makes the polling a little complicated, perhaps, because you have to watch for all chips to reach a finished state before you continue. Still thinking about the rest of what you wrote. My initial thoughts are this shouldn't really need a whole separate command set file. --> Steve ^ permalink raw reply [flat|nested] 20+ messages in thread
* DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) 2003-03-19 15:56 ` Steve Wahl @ 2003-03-19 19:38 ` Thayne Harbaugh 0 siblings, 0 replies; 20+ messages in thread From: Thayne Harbaugh @ 2003-03-19 19:38 UTC (permalink / raw) To: linux-mtd --=-kZtkePRDB816W7SZVvFx Content-Type: text/plain Content-Transfer-Encoding: quoted-printable On Wed, 2003-03-19 at 08:56, Steve Wahl wrote: > Still thinking about the rest of what you wrote. My initial thoughts > are this shouldn't really need a whole separate command set file. Yeah, I don't like making a new driver either. The concerns are knowing _not_ to check DQ5 and other status bits as well as knowing that a device does not support suspend/resume. That could be described in another field of the jedec_table[] - unless we can come up with a _reliable_ way of probing that functionality. I'm still thinking, too. I just wanted a starting point - sometimes it's hard to get going without some sample code. > --> Steve >=20 >=20 >=20 >=20 > ______________________________________________________ > Linux MTD discussion mailing list > http://lists.infradead.org/mailman/listinfo/linux-mtd/ --=20 Thayne Harbaugh Linux Networx --=-kZtkePRDB816W7SZVvFx Content-Type: application/pgp-signature; name=signature.asc Content-Description: This is a digitally signed message part -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.0.6 (GNU/Linux) Comment: For info see http://www.gnupg.org iD8DBQA+eMc2fsBPTKE6HMkRAiw2AJsFNarjJ6p1730Lv8MaTSKiHbJcOwCggltp MIcGi2FJjqSPg6efEAnLYjY= =Wb2R -----END PGP SIGNATURE----- --=-kZtkePRDB816W7SZVvFx-- ^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2003-03-19 19:38 UTC | newest] Thread overview: 20+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2003-03-12 0:25 DQ5 & DQ6 in chips/cfi_cmdset_0002.c (Dairy Queen 5 warning) Thayne Harbaugh 2003-03-12 15:44 ` John Burch 2003-03-12 16:35 ` Thayne Harbaugh 2003-03-12 16:27 ` Steve Wahl 2003-03-12 17:12 ` John Burch 2003-03-12 21:43 ` Steve Wahl 2003-03-12 22:17 ` John Burch 2003-03-13 7:17 ` David Woodhouse 2003-03-13 7:26 ` Russ Dill 2003-03-17 15:54 ` Thayne Harbaugh 2003-03-17 16:09 ` John Burch 2003-03-17 16:19 ` Steve Wahl 2003-03-17 18:27 ` Thayne Harbaugh 2003-03-18 16:51 ` Steve Wahl 2003-03-18 17:22 ` Thayne Harbaugh 2003-03-17 15:40 ` Thayne Harbaugh 2003-03-17 18:38 ` Thayne Harbaugh 2003-03-19 0:23 ` Thayne Harbaugh 2003-03-19 15:56 ` Steve Wahl 2003-03-19 19:38 ` Thayne Harbaugh
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox