initio.c 94 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174
  1. /**************************************************************************
  2. * Initio 9100 device driver for Linux.
  3. *
  4. * Copyright (c) 1994-1998 Initio Corporation
  5. * Copyright (c) 1998 Bas Vermeulen <bvermeul@blackstar.xs4all.nl>
  6. * All rights reserved.
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2, or (at your option)
  11. * any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; see the file COPYING. If not, write to
  20. * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21. *
  22. * --------------------------------------------------------------------------
  23. *
  24. * Redistribution and use in source and binary forms, with or without
  25. * modification, are permitted provided that the following conditions
  26. * are met:
  27. * 1. Redistributions of source code must retain the above copyright
  28. * notice, this list of conditions, and the following disclaimer,
  29. * without modification, immediately at the beginning of the file.
  30. * 2. Redistributions in binary form must reproduce the above copyright
  31. * notice, this list of conditions and the following disclaimer in the
  32. * documentation and/or other materials provided with the distribution.
  33. * 3. The name of the author may not be used to endorse or promote products
  34. * derived from this software without specific prior written permission.
  35. *
  36. * Where this Software is combined with software released under the terms of
  37. * the GNU General Public License ("GPL") and the terms of the GPL would require the
  38. * combined work to also be released under the terms of the GPL, the terms
  39. * and conditions of this License will apply in addition to those of the
  40. * GPL with the exception of any terms or conditions of this License that
  41. * conflict with, or are expressly prohibited by, the GPL.
  42. *
  43. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  44. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  45. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  46. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  47. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  48. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  49. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  50. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  51. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  52. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  53. * SUCH DAMAGE.
  54. *
  55. *************************************************************************
  56. *
  57. * DESCRIPTION:
  58. *
  59. * This is the Linux low-level SCSI driver for Initio INI-9X00U/UW SCSI host
  60. * adapters
  61. *
  62. * 08/06/97 hc - v1.01h
  63. * - Support inic-940 and inic-935
  64. * 09/26/97 hc - v1.01i
  65. * - Make correction from J.W. Schultz suggestion
  66. * 10/13/97 hc - Support reset function
  67. * 10/21/97 hc - v1.01j
  68. * - Support 32 LUN (SCSI 3)
  69. * 01/14/98 hc - v1.01k
  70. * - Fix memory allocation problem
  71. * 03/04/98 hc - v1.01l
  72. * - Fix tape rewind which will hang the system problem
  73. * - Set can_queue to tul_num_scb
  74. * 06/25/98 hc - v1.01m
  75. * - Get it work for kernel version >= 2.1.75
  76. * - Dynamic assign SCSI bus reset holding time in init_tulip()
  77. * 07/02/98 hc - v1.01n
  78. * - Support 0002134A
  79. * 08/07/98 hc - v1.01o
  80. * - Change the tul_abort_srb routine to use scsi_done. <01>
  81. * 09/07/98 hl - v1.02
  82. * - Change the INI9100U define and proc_dir_entry to
  83. * reflect the newer Kernel 2.1.118, but the v1.o1o
  84. * should work with Kernel 2.1.118.
  85. * 09/20/98 wh - v1.02a
  86. * - Support Abort command.
  87. * - Handle reset routine.
  88. * 09/21/98 hl - v1.03
  89. * - remove comments.
  90. * 12/09/98 bv - v1.03a
  91. * - Removed unused code
  92. * 12/13/98 bv - v1.03b
  93. * - Remove cli() locking for kernels >= 2.1.95. This uses
  94. * spinlocks to serialize access to the pSRB_head and
  95. * pSRB_tail members of the HCS structure.
  96. * 09/01/99 bv - v1.03d
  97. * - Fixed a deadlock problem in SMP.
  98. * 21/01/99 bv - v1.03e
  99. * - Add support for the Domex 3192U PCI SCSI
  100. * This is a slightly modified patch by
  101. * Brian Macy <bmacy@sunshinecomputing.com>
  102. * 22/02/99 bv - v1.03f
  103. * - Didn't detect the INIC-950 in 2.0.x correctly.
  104. * Now fixed.
  105. * 05/07/99 bv - v1.03g
  106. * - Changed the assumption that HZ = 100
  107. * 10/17/03 mc - v1.04
  108. * - added new DMA API support
  109. * 06/01/04 jmd - v1.04a
  110. * - Re-add reset_bus support
  111. **************************************************************************/
  112. #include <linux/module.h>
  113. #include <linux/errno.h>
  114. #include <linux/delay.h>
  115. #include <linux/pci.h>
  116. #include <linux/init.h>
  117. #include <linux/blkdev.h>
  118. #include <linux/spinlock.h>
  119. #include <linux/stat.h>
  120. #include <linux/kernel.h>
  121. #include <linux/proc_fs.h>
  122. #include <linux/string.h>
  123. #include <linux/interrupt.h>
  124. #include <linux/ioport.h>
  125. #include <linux/slab.h>
  126. #include <linux/jiffies.h>
  127. #include <linux/dma-mapping.h>
  128. #include <asm/io.h>
  129. #include <scsi/scsi.h>
  130. #include <scsi/scsi_cmnd.h>
  131. #include <scsi/scsi_device.h>
  132. #include <scsi/scsi_host.h>
  133. #include <scsi/scsi_tcq.h>
  134. #include "initio.h"
  135. #define SENSE_SIZE 14
  136. #define i91u_MAXQUEUE 2
  137. #define i91u_REVID "Initio INI-9X00U/UW SCSI device driver; Revision: 1.04a"
  138. #define I950_DEVICE_ID 0x9500 /* Initio's inic-950 product ID */
  139. #define I940_DEVICE_ID 0x9400 /* Initio's inic-940 product ID */
  140. #define I935_DEVICE_ID 0x9401 /* Initio's inic-935 product ID */
  141. #define I920_DEVICE_ID 0x0002 /* Initio's other product ID */
  142. #ifdef DEBUG_i91u
  143. static unsigned int i91u_debug = DEBUG_DEFAULT;
  144. #endif
  145. #define TUL_RDWORD(x,y) (short)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) ))
  146. typedef struct PCI_ID_Struc {
  147. unsigned short vendor_id;
  148. unsigned short device_id;
  149. } PCI_ID;
  150. static int tul_num_ch = 4; /* Maximum 4 adapters */
  151. static int tul_num_scb;
  152. static int tul_tag_enable = 1;
  153. static SCB *tul_scb;
  154. #ifdef DEBUG_i91u
  155. static int setup_debug = 0;
  156. #endif
  157. static void i91uSCBPost(BYTE * pHcb, BYTE * pScb);
  158. /* PCI Devices supported by this driver */
  159. static struct pci_device_id i91u_pci_devices[] = {
  160. { PCI_VENDOR_ID_INIT, I950_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
  161. { PCI_VENDOR_ID_INIT, I940_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
  162. { PCI_VENDOR_ID_INIT, I935_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
  163. { PCI_VENDOR_ID_INIT, I920_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
  164. { PCI_VENDOR_ID_DOMEX, I920_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
  165. { }
  166. };
  167. MODULE_DEVICE_TABLE(pci, i91u_pci_devices);
  168. #define DEBUG_INTERRUPT 0
  169. #define DEBUG_QUEUE 0
  170. #define DEBUG_STATE 0
  171. #define INT_DISC 0
  172. /*--- external functions --*/
  173. static void tul_se2_wait(void);
  174. /*--- forward refrence ---*/
  175. static SCB *tul_find_busy_scb(HCS * pCurHcb, WORD tarlun);
  176. static SCB *tul_find_done_scb(HCS * pCurHcb);
  177. static int tulip_main(HCS * pCurHcb);
  178. static int tul_next_state(HCS * pCurHcb);
  179. static int tul_state_1(HCS * pCurHcb);
  180. static int tul_state_2(HCS * pCurHcb);
  181. static int tul_state_3(HCS * pCurHcb);
  182. static int tul_state_4(HCS * pCurHcb);
  183. static int tul_state_5(HCS * pCurHcb);
  184. static int tul_state_6(HCS * pCurHcb);
  185. static int tul_state_7(HCS * pCurHcb);
  186. static int tul_xfer_data_in(HCS * pCurHcb);
  187. static int tul_xfer_data_out(HCS * pCurHcb);
  188. static int tul_xpad_in(HCS * pCurHcb);
  189. static int tul_xpad_out(HCS * pCurHcb);
  190. static int tul_status_msg(HCS * pCurHcb);
  191. static int tul_msgin(HCS * pCurHcb);
  192. static int tul_msgin_sync(HCS * pCurHcb);
  193. static int tul_msgin_accept(HCS * pCurHcb);
  194. static int tul_msgout_reject(HCS * pCurHcb);
  195. static int tul_msgin_extend(HCS * pCurHcb);
  196. static int tul_msgout_ide(HCS * pCurHcb);
  197. static int tul_msgout_abort_targ(HCS * pCurHcb);
  198. static int tul_msgout_abort_tag(HCS * pCurHcb);
  199. static int tul_bus_device_reset(HCS * pCurHcb);
  200. static void tul_select_atn(HCS * pCurHcb, SCB * pCurScb);
  201. static void tul_select_atn3(HCS * pCurHcb, SCB * pCurScb);
  202. static void tul_select_atn_stop(HCS * pCurHcb, SCB * pCurScb);
  203. static int int_tul_busfree(HCS * pCurHcb);
  204. static int int_tul_scsi_rst(HCS * pCurHcb);
  205. static int int_tul_bad_seq(HCS * pCurHcb);
  206. static int int_tul_resel(HCS * pCurHcb);
  207. static int tul_sync_done(HCS * pCurHcb);
  208. static int wdtr_done(HCS * pCurHcb);
  209. static int wait_tulip(HCS * pCurHcb);
  210. static int tul_wait_done_disc(HCS * pCurHcb);
  211. static int tul_wait_disc(HCS * pCurHcb);
  212. static void tulip_scsi(HCS * pCurHcb);
  213. static int tul_post_scsi_rst(HCS * pCurHcb);
  214. static void tul_se2_ew_en(WORD CurBase);
  215. static void tul_se2_ew_ds(WORD CurBase);
  216. static int tul_se2_rd_all(WORD CurBase);
  217. static void tul_se2_update_all(WORD CurBase); /* setup default pattern */
  218. static void tul_read_eeprom(WORD CurBase);
  219. /* ---- INTERNAL VARIABLES ---- */
  220. static HCS tul_hcs[MAX_SUPPORTED_ADAPTERS];
  221. static INI_ADPT_STRUCT i91u_adpt[MAX_SUPPORTED_ADAPTERS];
  222. /*NVRAM nvram, *nvramp = &nvram; */
  223. static NVRAM i91unvram;
  224. static NVRAM *i91unvramp;
  225. static UCHAR i91udftNvRam[64] =
  226. {
  227. /*----------- header -----------*/
  228. 0x25, 0xc9, /* Signature */
  229. 0x40, /* Size */
  230. 0x01, /* Revision */
  231. /* -- Host Adapter Structure -- */
  232. 0x95, /* ModelByte0 */
  233. 0x00, /* ModelByte1 */
  234. 0x00, /* ModelInfo */
  235. 0x01, /* NumOfCh */
  236. NBC1_DEFAULT, /* BIOSConfig1 */
  237. 0, /* BIOSConfig2 */
  238. 0, /* HAConfig1 */
  239. 0, /* HAConfig2 */
  240. /* SCSI channel 0 and target Structure */
  241. 7, /* SCSIid */
  242. NCC1_DEFAULT, /* SCSIconfig1 */
  243. 0, /* SCSIconfig2 */
  244. 0x10, /* NumSCSItarget */
  245. NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
  246. NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
  247. NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
  248. NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
  249. /* SCSI channel 1 and target Structure */
  250. 7, /* SCSIid */
  251. NCC1_DEFAULT, /* SCSIconfig1 */
  252. 0, /* SCSIconfig2 */
  253. 0x10, /* NumSCSItarget */
  254. NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
  255. NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
  256. NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
  257. NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT,
  258. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  259. 0, 0}; /* - CheckSum - */
  260. static UCHAR tul_rate_tbl[8] = /* fast 20 */
  261. {
  262. /* nanosecond devide by 4 */
  263. 12, /* 50ns, 20M */
  264. 18, /* 75ns, 13.3M */
  265. 25, /* 100ns, 10M */
  266. 31, /* 125ns, 8M */
  267. 37, /* 150ns, 6.6M */
  268. 43, /* 175ns, 5.7M */
  269. 50, /* 200ns, 5M */
  270. 62 /* 250ns, 4M */
  271. };
  272. static void tul_do_pause(unsigned amount)
  273. { /* Pause for amount jiffies */
  274. unsigned long the_time = jiffies + amount;
  275. while (time_before_eq(jiffies, the_time));
  276. }
  277. /*-- forward reference --*/
  278. /*******************************************************************
  279. Use memeory refresh time ~ 15us * 2
  280. ********************************************************************/
  281. void tul_se2_wait(void)
  282. {
  283. #if 1
  284. udelay(30);
  285. #else
  286. UCHAR readByte;
  287. readByte = TUL_RD(0, 0x61);
  288. if ((readByte & 0x10) == 0x10) {
  289. for (;;) {
  290. readByte = TUL_RD(0, 0x61);
  291. if ((readByte & 0x10) == 0x10)
  292. break;
  293. }
  294. for (;;) {
  295. readByte = TUL_RD(0, 0x61);
  296. if ((readByte & 0x10) != 0x10)
  297. break;
  298. }
  299. } else {
  300. for (;;) {
  301. readByte = TUL_RD(0, 0x61);
  302. if ((readByte & 0x10) == 0x10)
  303. break;
  304. }
  305. for (;;) {
  306. readByte = TUL_RD(0, 0x61);
  307. if ((readByte & 0x10) != 0x10)
  308. break;
  309. }
  310. }
  311. #endif
  312. }
  313. /******************************************************************
  314. Input: instruction for Serial E2PROM
  315. EX: se2_rd(0 call se2_instr() to send address and read command
  316. StartBit OP_Code Address Data
  317. --------- -------- ------------------ -------
  318. 1 1 , 0 A5,A4,A3,A2,A1,A0 D15-D0
  319. +-----------------------------------------------------
  320. |
  321. CS -----+
  322. +--+ +--+ +--+ +--+ +--+
  323. ^ | ^ | ^ | ^ | ^ |
  324. | | | | | | | | | |
  325. CLK -------+ +--+ +--+ +--+ +--+ +--
  326. (leading edge trigger)
  327. +--1-----1--+
  328. | SB OP | OP A5 A4
  329. DI ----+ +--0------------------
  330. (address and cmd sent to nvram)
  331. -------------------------------------------+
  332. |
  333. DO +---
  334. (data sent from nvram)
  335. ******************************************************************/
  336. static void tul_se2_instr(WORD CurBase, UCHAR instr)
  337. {
  338. int i;
  339. UCHAR b;
  340. TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2DO); /* cs+start bit */
  341. tul_se2_wait();
  342. TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK | SE2DO); /* +CLK */
  343. tul_se2_wait();
  344. for (i = 0; i < 8; i++) {
  345. if (instr & 0x80)
  346. b = SE2CS | SE2DO; /* -CLK+dataBit */
  347. else
  348. b = SE2CS; /* -CLK */
  349. TUL_WR(CurBase + TUL_NVRAM, b);
  350. tul_se2_wait();
  351. TUL_WR(CurBase + TUL_NVRAM, b | SE2CLK); /* +CLK */
  352. tul_se2_wait();
  353. instr <<= 1;
  354. }
  355. TUL_WR(CurBase + TUL_NVRAM, SE2CS); /* -CLK */
  356. tul_se2_wait();
  357. return;
  358. }
  359. /******************************************************************
  360. Function name : tul_se2_ew_en
  361. Description : Enable erase/write state of serial EEPROM
  362. ******************************************************************/
  363. void tul_se2_ew_en(WORD CurBase)
  364. {
  365. tul_se2_instr(CurBase, 0x30); /* EWEN */
  366. TUL_WR(CurBase + TUL_NVRAM, 0); /* -CS */
  367. tul_se2_wait();
  368. return;
  369. }
  370. /************************************************************************
  371. Disable erase/write state of serial EEPROM
  372. *************************************************************************/
  373. void tul_se2_ew_ds(WORD CurBase)
  374. {
  375. tul_se2_instr(CurBase, 0); /* EWDS */
  376. TUL_WR(CurBase + TUL_NVRAM, 0); /* -CS */
  377. tul_se2_wait();
  378. return;
  379. }
  380. /******************************************************************
  381. Input :address of Serial E2PROM
  382. Output :value stored in Serial E2PROM
  383. *******************************************************************/
  384. static USHORT tul_se2_rd(WORD CurBase, ULONG adr)
  385. {
  386. UCHAR instr, readByte;
  387. USHORT readWord;
  388. int i;
  389. instr = (UCHAR) (adr | 0x80);
  390. tul_se2_instr(CurBase, instr); /* READ INSTR */
  391. readWord = 0;
  392. for (i = 15; i >= 0; i--) {
  393. TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK); /* +CLK */
  394. tul_se2_wait();
  395. TUL_WR(CurBase + TUL_NVRAM, SE2CS); /* -CLK */
  396. /* sample data after the following edge of clock */
  397. readByte = TUL_RD(CurBase, TUL_NVRAM);
  398. readByte &= SE2DI;
  399. readWord += (readByte << i);
  400. tul_se2_wait(); /* 6/20/95 */
  401. }
  402. TUL_WR(CurBase + TUL_NVRAM, 0); /* no chip select */
  403. tul_se2_wait();
  404. return readWord;
  405. }
  406. /******************************************************************
  407. Input: new value in Serial E2PROM, address of Serial E2PROM
  408. *******************************************************************/
  409. static void tul_se2_wr(WORD CurBase, UCHAR adr, USHORT writeWord)
  410. {
  411. UCHAR readByte;
  412. UCHAR instr;
  413. int i;
  414. instr = (UCHAR) (adr | 0x40);
  415. tul_se2_instr(CurBase, instr); /* WRITE INSTR */
  416. for (i = 15; i >= 0; i--) {
  417. if (writeWord & 0x8000)
  418. TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2DO); /* -CLK+dataBit 1 */
  419. else
  420. TUL_WR(CurBase + TUL_NVRAM, SE2CS); /* -CLK+dataBit 0 */
  421. tul_se2_wait();
  422. TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK); /* +CLK */
  423. tul_se2_wait();
  424. writeWord <<= 1;
  425. }
  426. TUL_WR(CurBase + TUL_NVRAM, SE2CS); /* -CLK */
  427. tul_se2_wait();
  428. TUL_WR(CurBase + TUL_NVRAM, 0); /* -CS */
  429. tul_se2_wait();
  430. TUL_WR(CurBase + TUL_NVRAM, SE2CS); /* +CS */
  431. tul_se2_wait();
  432. for (;;) {
  433. TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK); /* +CLK */
  434. tul_se2_wait();
  435. TUL_WR(CurBase + TUL_NVRAM, SE2CS); /* -CLK */
  436. tul_se2_wait();
  437. if ((readByte = TUL_RD(CurBase, TUL_NVRAM)) & SE2DI)
  438. break; /* write complete */
  439. }
  440. TUL_WR(CurBase + TUL_NVRAM, 0); /* -CS */
  441. return;
  442. }
  443. /***********************************************************************
  444. Read SCSI H/A configuration parameters from serial EEPROM
  445. ************************************************************************/
  446. int tul_se2_rd_all(WORD CurBase)
  447. {
  448. int i;
  449. ULONG chksum = 0;
  450. USHORT *np;
  451. i91unvramp = &i91unvram;
  452. np = (USHORT *) i91unvramp;
  453. for (i = 0; i < 32; i++) {
  454. *np++ = tul_se2_rd(CurBase, i);
  455. }
  456. /*--------------------Is signature "ini" ok ? ----------------*/
  457. if (i91unvramp->NVM_Signature != INI_SIGNATURE)
  458. return -1;
  459. /*---------------------- Is ckecksum ok ? ----------------------*/
  460. np = (USHORT *) i91unvramp;
  461. for (i = 0; i < 31; i++)
  462. chksum += *np++;
  463. if (i91unvramp->NVM_CheckSum != (USHORT) chksum)
  464. return -1;
  465. return 1;
  466. }
  467. /***********************************************************************
  468. Update SCSI H/A configuration parameters from serial EEPROM
  469. ************************************************************************/
  470. void tul_se2_update_all(WORD CurBase)
  471. { /* setup default pattern */
  472. int i;
  473. ULONG chksum = 0;
  474. USHORT *np, *np1;
  475. i91unvramp = &i91unvram;
  476. /* Calculate checksum first */
  477. np = (USHORT *) i91udftNvRam;
  478. for (i = 0; i < 31; i++)
  479. chksum += *np++;
  480. *np = (USHORT) chksum;
  481. tul_se2_ew_en(CurBase); /* Enable write */
  482. np = (USHORT *) i91udftNvRam;
  483. np1 = (USHORT *) i91unvramp;
  484. for (i = 0; i < 32; i++, np++, np1++) {
  485. if (*np != *np1) {
  486. tul_se2_wr(CurBase, i, *np);
  487. }
  488. }
  489. tul_se2_ew_ds(CurBase); /* Disable write */
  490. return;
  491. }
  492. /*************************************************************************
  493. Function name : read_eeprom
  494. **************************************************************************/
  495. void tul_read_eeprom(WORD CurBase)
  496. {
  497. UCHAR gctrl;
  498. i91unvramp = &i91unvram;
  499. /*------Enable EEProm programming ---*/
  500. gctrl = TUL_RD(CurBase, TUL_GCTRL);
  501. TUL_WR(CurBase + TUL_GCTRL, gctrl | TUL_GCTRL_EEPROM_BIT);
  502. if (tul_se2_rd_all(CurBase) != 1) {
  503. tul_se2_update_all(CurBase); /* setup default pattern */
  504. tul_se2_rd_all(CurBase); /* load again */
  505. }
  506. /*------ Disable EEProm programming ---*/
  507. gctrl = TUL_RD(CurBase, TUL_GCTRL);
  508. TUL_WR(CurBase + TUL_GCTRL, gctrl & ~TUL_GCTRL_EEPROM_BIT);
  509. } /* read_eeprom */
  510. static int Addi91u_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt,
  511. BYTE bBus, BYTE bDevice)
  512. {
  513. int i, j;
  514. for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) {
  515. if (i91u_adpt[i].ADPT_BIOS < wBIOS)
  516. continue;
  517. if (i91u_adpt[i].ADPT_BIOS == wBIOS) {
  518. if (i91u_adpt[i].ADPT_BASE == wBASE) {
  519. if (i91u_adpt[i].ADPT_Bus != 0xFF)
  520. return 1;
  521. } else if (i91u_adpt[i].ADPT_BASE < wBASE)
  522. continue;
  523. }
  524. for (j = MAX_SUPPORTED_ADAPTERS - 1; j > i; j--) {
  525. i91u_adpt[j].ADPT_BASE = i91u_adpt[j - 1].ADPT_BASE;
  526. i91u_adpt[j].ADPT_INTR = i91u_adpt[j - 1].ADPT_INTR;
  527. i91u_adpt[j].ADPT_BIOS = i91u_adpt[j - 1].ADPT_BIOS;
  528. i91u_adpt[j].ADPT_Bus = i91u_adpt[j - 1].ADPT_Bus;
  529. i91u_adpt[j].ADPT_Device = i91u_adpt[j - 1].ADPT_Device;
  530. }
  531. i91u_adpt[i].ADPT_BASE = wBASE;
  532. i91u_adpt[i].ADPT_INTR = bInterrupt;
  533. i91u_adpt[i].ADPT_BIOS = wBIOS;
  534. i91u_adpt[i].ADPT_Bus = bBus;
  535. i91u_adpt[i].ADPT_Device = bDevice;
  536. return 0;
  537. }
  538. return 1;
  539. }
  540. static void init_i91uAdapter_table(void)
  541. {
  542. int i;
  543. for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) { /* Initialize adapter structure */
  544. i91u_adpt[i].ADPT_BIOS = 0xffff;
  545. i91u_adpt[i].ADPT_BASE = 0xffff;
  546. i91u_adpt[i].ADPT_INTR = 0xff;
  547. i91u_adpt[i].ADPT_Bus = 0xff;
  548. i91u_adpt[i].ADPT_Device = 0xff;
  549. }
  550. return;
  551. }
  552. static void tul_stop_bm(HCS * pCurHcb)
  553. {
  554. if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) { /* if DMA xfer is pending, abort DMA xfer */
  555. TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_ABT | TAX_X_CLR_FIFO);
  556. /* wait Abort DMA xfer done */
  557. while ((TUL_RD(pCurHcb->HCS_Base, TUL_Int) & XABT) == 0);
  558. }
  559. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
  560. }
  561. /***************************************************************************/
  562. static void get_tulipPCIConfig(HCS * pCurHcb, int ch_idx)
  563. {
  564. pCurHcb->HCS_Base = i91u_adpt[ch_idx].ADPT_BASE; /* Supply base address */
  565. pCurHcb->HCS_BIOS = i91u_adpt[ch_idx].ADPT_BIOS; /* Supply BIOS address */
  566. pCurHcb->HCS_Intr = i91u_adpt[ch_idx].ADPT_INTR; /* Supply interrupt line */
  567. return;
  568. }
  569. /***************************************************************************/
  570. static int tul_reset_scsi(HCS * pCurHcb, int seconds)
  571. {
  572. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_RST_BUS);
  573. while (!((pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt)) & TSS_SCSIRST_INT));
  574. /* reset tulip chip */
  575. TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, 0);
  576. /* Stall for a while, wait for target's firmware ready,make it 2 sec ! */
  577. /* SONY 5200 tape drive won't work if only stall for 1 sec */
  578. tul_do_pause(seconds * HZ);
  579. TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
  580. return (SCSI_RESET_SUCCESS);
  581. }
  582. /***************************************************************************/
  583. static int init_tulip(HCS * pCurHcb, SCB * scbp, int tul_num_scb,
  584. BYTE * pbBiosAdr, int seconds)
  585. {
  586. int i;
  587. BYTE *pwFlags;
  588. BYTE *pbHeads;
  589. SCB *pTmpScb, *pPrevScb = NULL;
  590. pCurHcb->HCS_NumScbs = tul_num_scb;
  591. pCurHcb->HCS_Semaph = 1;
  592. spin_lock_init(&pCurHcb->HCS_SemaphLock);
  593. pCurHcb->HCS_JSStatus0 = 0;
  594. pCurHcb->HCS_Scb = scbp;
  595. pCurHcb->HCS_NxtPend = scbp;
  596. pCurHcb->HCS_NxtAvail = scbp;
  597. for (i = 0, pTmpScb = scbp; i < tul_num_scb; i++, pTmpScb++) {
  598. pTmpScb->SCB_TagId = i;
  599. if (i != 0)
  600. pPrevScb->SCB_NxtScb = pTmpScb;
  601. pPrevScb = pTmpScb;
  602. }
  603. pPrevScb->SCB_NxtScb = NULL;
  604. pCurHcb->HCS_ScbEnd = pTmpScb;
  605. pCurHcb->HCS_FirstAvail = scbp;
  606. pCurHcb->HCS_LastAvail = pPrevScb;
  607. spin_lock_init(&pCurHcb->HCS_AvailLock);
  608. pCurHcb->HCS_FirstPend = NULL;
  609. pCurHcb->HCS_LastPend = NULL;
  610. pCurHcb->HCS_FirstBusy = NULL;
  611. pCurHcb->HCS_LastBusy = NULL;
  612. pCurHcb->HCS_FirstDone = NULL;
  613. pCurHcb->HCS_LastDone = NULL;
  614. pCurHcb->HCS_ActScb = NULL;
  615. pCurHcb->HCS_ActTcs = NULL;
  616. tul_read_eeprom(pCurHcb->HCS_Base);
  617. /*---------- get H/A configuration -------------*/
  618. if (i91unvramp->NVM_SCSIInfo[0].NVM_NumOfTarg == 8)
  619. pCurHcb->HCS_MaxTar = 8;
  620. else
  621. pCurHcb->HCS_MaxTar = 16;
  622. pCurHcb->HCS_Config = i91unvramp->NVM_SCSIInfo[0].NVM_ChConfig1;
  623. pCurHcb->HCS_SCSI_ID = i91unvramp->NVM_SCSIInfo[0].NVM_ChSCSIID;
  624. pCurHcb->HCS_IdMask = ~(1 << pCurHcb->HCS_SCSI_ID);
  625. #ifdef CHK_PARITY
  626. /* Enable parity error response */
  627. TUL_WR(pCurHcb->HCS_Base + TUL_PCMD, TUL_RD(pCurHcb->HCS_Base, TUL_PCMD) | 0x40);
  628. #endif
  629. /* Mask all the interrupt */
  630. TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
  631. tul_stop_bm(pCurHcb);
  632. /* --- Initialize the tulip --- */
  633. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_RST_CHIP);
  634. /* program HBA's SCSI ID */
  635. TUL_WR(pCurHcb->HCS_Base + TUL_SScsiId, pCurHcb->HCS_SCSI_ID << 4);
  636. /* Enable Initiator Mode ,phase latch,alternate sync period mode,
  637. disable SCSI reset */
  638. if (pCurHcb->HCS_Config & HCC_EN_PAR)
  639. pCurHcb->HCS_SConf1 = (TSC_INITDEFAULT | TSC_EN_SCSI_PAR);
  640. else
  641. pCurHcb->HCS_SConf1 = (TSC_INITDEFAULT);
  642. TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurHcb->HCS_SConf1);
  643. /* Enable HW reselect */
  644. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);
  645. TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, 0);
  646. /* selection time out = 250 ms */
  647. TUL_WR(pCurHcb->HCS_Base + TUL_STimeOut, 153);
  648. /*--------- Enable SCSI terminator -----*/
  649. TUL_WR(pCurHcb->HCS_Base + TUL_XCtrl, (pCurHcb->HCS_Config & (HCC_ACT_TERM1 | HCC_ACT_TERM2)));
  650. TUL_WR(pCurHcb->HCS_Base + TUL_GCTRL1,
  651. ((pCurHcb->HCS_Config & HCC_AUTO_TERM) >> 4) | (TUL_RD(pCurHcb->HCS_Base, TUL_GCTRL1) & 0xFE));
  652. for (i = 0,
  653. pwFlags = & (i91unvramp->NVM_SCSIInfo[0].NVM_Targ0Config),
  654. pbHeads = pbBiosAdr + 0x180;
  655. i < pCurHcb->HCS_MaxTar;
  656. i++, pwFlags++) {
  657. pCurHcb->HCS_Tcs[i].TCS_Flags = *pwFlags & ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
  658. if (pCurHcb->HCS_Tcs[i].TCS_Flags & TCF_EN_255)
  659. pCurHcb->HCS_Tcs[i].TCS_DrvFlags = TCF_DRV_255_63;
  660. else
  661. pCurHcb->HCS_Tcs[i].TCS_DrvFlags = 0;
  662. pCurHcb->HCS_Tcs[i].TCS_JS_Period = 0;
  663. pCurHcb->HCS_Tcs[i].TCS_SConfig0 = pCurHcb->HCS_SConf1;
  664. pCurHcb->HCS_Tcs[i].TCS_DrvHead = *pbHeads++;
  665. if (pCurHcb->HCS_Tcs[i].TCS_DrvHead == 255)
  666. pCurHcb->HCS_Tcs[i].TCS_DrvFlags = TCF_DRV_255_63;
  667. else
  668. pCurHcb->HCS_Tcs[i].TCS_DrvFlags = 0;
  669. pCurHcb->HCS_Tcs[i].TCS_DrvSector = *pbHeads++;
  670. pCurHcb->HCS_Tcs[i].TCS_Flags &= ~TCF_BUSY;
  671. pCurHcb->HCS_ActTags[i] = 0;
  672. pCurHcb->HCS_MaxTags[i] = 0xFF;
  673. } /* for */
  674. printk("i91u: PCI Base=0x%04X, IRQ=%d, BIOS=0x%04X0, SCSI ID=%d\n",
  675. pCurHcb->HCS_Base, pCurHcb->HCS_Intr,
  676. pCurHcb->HCS_BIOS, pCurHcb->HCS_SCSI_ID);
  677. /*------------------- reset SCSI Bus ---------------------------*/
  678. if (pCurHcb->HCS_Config & HCC_SCSI_RESET) {
  679. printk("i91u: Reset SCSI Bus ... \n");
  680. tul_reset_scsi(pCurHcb, seconds);
  681. }
  682. TUL_WR(pCurHcb->HCS_Base + TUL_SCFG1, 0x17);
  683. TUL_WR(pCurHcb->HCS_Base + TUL_SIntEnable, 0xE9);
  684. return (0);
  685. }
  686. /***************************************************************************/
  687. static SCB *tul_alloc_scb(HCS * hcsp)
  688. {
  689. SCB *pTmpScb;
  690. ULONG flags;
  691. spin_lock_irqsave(&(hcsp->HCS_AvailLock), flags);
  692. if ((pTmpScb = hcsp->HCS_FirstAvail) != NULL) {
  693. #if DEBUG_QUEUE
  694. printk("find scb at %08lx\n", (ULONG) pTmpScb);
  695. #endif
  696. if ((hcsp->HCS_FirstAvail = pTmpScb->SCB_NxtScb) == NULL)
  697. hcsp->HCS_LastAvail = NULL;
  698. pTmpScb->SCB_NxtScb = NULL;
  699. pTmpScb->SCB_Status = SCB_RENT;
  700. }
  701. spin_unlock_irqrestore(&(hcsp->HCS_AvailLock), flags);
  702. return (pTmpScb);
  703. }
  704. /***************************************************************************/
  705. static void tul_release_scb(HCS * hcsp, SCB * scbp)
  706. {
  707. ULONG flags;
  708. #if DEBUG_QUEUE
  709. printk("Release SCB %lx; ", (ULONG) scbp);
  710. #endif
  711. spin_lock_irqsave(&(hcsp->HCS_AvailLock), flags);
  712. scbp->SCB_Srb = NULL;
  713. scbp->SCB_Status = 0;
  714. scbp->SCB_NxtScb = NULL;
  715. if (hcsp->HCS_LastAvail != NULL) {
  716. hcsp->HCS_LastAvail->SCB_NxtScb = scbp;
  717. hcsp->HCS_LastAvail = scbp;
  718. } else {
  719. hcsp->HCS_FirstAvail = scbp;
  720. hcsp->HCS_LastAvail = scbp;
  721. }
  722. spin_unlock_irqrestore(&(hcsp->HCS_AvailLock), flags);
  723. }
  724. /***************************************************************************/
  725. static void tul_append_pend_scb(HCS * pCurHcb, SCB * scbp)
  726. {
  727. #if DEBUG_QUEUE
  728. printk("Append pend SCB %lx; ", (ULONG) scbp);
  729. #endif
  730. scbp->SCB_Status = SCB_PEND;
  731. scbp->SCB_NxtScb = NULL;
  732. if (pCurHcb->HCS_LastPend != NULL) {
  733. pCurHcb->HCS_LastPend->SCB_NxtScb = scbp;
  734. pCurHcb->HCS_LastPend = scbp;
  735. } else {
  736. pCurHcb->HCS_FirstPend = scbp;
  737. pCurHcb->HCS_LastPend = scbp;
  738. }
  739. }
  740. /***************************************************************************/
  741. static void tul_push_pend_scb(HCS * pCurHcb, SCB * scbp)
  742. {
  743. #if DEBUG_QUEUE
  744. printk("Push pend SCB %lx; ", (ULONG) scbp);
  745. #endif
  746. scbp->SCB_Status = SCB_PEND;
  747. if ((scbp->SCB_NxtScb = pCurHcb->HCS_FirstPend) != NULL) {
  748. pCurHcb->HCS_FirstPend = scbp;
  749. } else {
  750. pCurHcb->HCS_FirstPend = scbp;
  751. pCurHcb->HCS_LastPend = scbp;
  752. }
  753. }
  754. /***************************************************************************/
  755. static SCB *tul_find_first_pend_scb(HCS * pCurHcb)
  756. {
  757. SCB *pFirstPend;
  758. pFirstPend = pCurHcb->HCS_FirstPend;
  759. while (pFirstPend != NULL) {
  760. if (pFirstPend->SCB_Opcode != ExecSCSI) {
  761. return (pFirstPend);
  762. }
  763. if (pFirstPend->SCB_TagMsg == 0) {
  764. if ((pCurHcb->HCS_ActTags[pFirstPend->SCB_Target] == 0) &&
  765. !(pCurHcb->HCS_Tcs[pFirstPend->SCB_Target].TCS_Flags & TCF_BUSY)) {
  766. return (pFirstPend);
  767. }
  768. } else {
  769. if ((pCurHcb->HCS_ActTags[pFirstPend->SCB_Target] >=
  770. pCurHcb->HCS_MaxTags[pFirstPend->SCB_Target]) |
  771. (pCurHcb->HCS_Tcs[pFirstPend->SCB_Target].TCS_Flags & TCF_BUSY)) {
  772. pFirstPend = pFirstPend->SCB_NxtScb;
  773. continue;
  774. }
  775. return (pFirstPend);
  776. }
  777. pFirstPend = pFirstPend->SCB_NxtScb;
  778. }
  779. return (pFirstPend);
  780. }
  781. /***************************************************************************/
  782. static void tul_unlink_pend_scb(HCS * pCurHcb, SCB * pCurScb)
  783. {
  784. SCB *pTmpScb, *pPrevScb;
  785. #if DEBUG_QUEUE
  786. printk("unlink pend SCB %lx; ", (ULONG) pCurScb);
  787. #endif
  788. pPrevScb = pTmpScb = pCurHcb->HCS_FirstPend;
  789. while (pTmpScb != NULL) {
  790. if (pCurScb == pTmpScb) { /* Unlink this SCB */
  791. if (pTmpScb == pCurHcb->HCS_FirstPend) {
  792. if ((pCurHcb->HCS_FirstPend = pTmpScb->SCB_NxtScb) == NULL)
  793. pCurHcb->HCS_LastPend = NULL;
  794. } else {
  795. pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
  796. if (pTmpScb == pCurHcb->HCS_LastPend)
  797. pCurHcb->HCS_LastPend = pPrevScb;
  798. }
  799. pTmpScb->SCB_NxtScb = NULL;
  800. break;
  801. }
  802. pPrevScb = pTmpScb;
  803. pTmpScb = pTmpScb->SCB_NxtScb;
  804. }
  805. return;
  806. }
  807. /***************************************************************************/
  808. static void tul_append_busy_scb(HCS * pCurHcb, SCB * scbp)
  809. {
  810. #if DEBUG_QUEUE
  811. printk("append busy SCB %lx; ", (ULONG) scbp);
  812. #endif
  813. if (scbp->SCB_TagMsg)
  814. pCurHcb->HCS_ActTags[scbp->SCB_Target]++;
  815. else
  816. pCurHcb->HCS_Tcs[scbp->SCB_Target].TCS_Flags |= TCF_BUSY;
  817. scbp->SCB_Status = SCB_BUSY;
  818. scbp->SCB_NxtScb = NULL;
  819. if (pCurHcb->HCS_LastBusy != NULL) {
  820. pCurHcb->HCS_LastBusy->SCB_NxtScb = scbp;
  821. pCurHcb->HCS_LastBusy = scbp;
  822. } else {
  823. pCurHcb->HCS_FirstBusy = scbp;
  824. pCurHcb->HCS_LastBusy = scbp;
  825. }
  826. }
  827. /***************************************************************************/
  828. static SCB *tul_pop_busy_scb(HCS * pCurHcb)
  829. {
  830. SCB *pTmpScb;
  831. if ((pTmpScb = pCurHcb->HCS_FirstBusy) != NULL) {
  832. if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL)
  833. pCurHcb->HCS_LastBusy = NULL;
  834. pTmpScb->SCB_NxtScb = NULL;
  835. if (pTmpScb->SCB_TagMsg)
  836. pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--;
  837. else
  838. pCurHcb->HCS_Tcs[pTmpScb->SCB_Target].TCS_Flags &= ~TCF_BUSY;
  839. }
  840. #if DEBUG_QUEUE
  841. printk("Pop busy SCB %lx; ", (ULONG) pTmpScb);
  842. #endif
  843. return (pTmpScb);
  844. }
  845. /***************************************************************************/
  846. static void tul_unlink_busy_scb(HCS * pCurHcb, SCB * pCurScb)
  847. {
  848. SCB *pTmpScb, *pPrevScb;
  849. #if DEBUG_QUEUE
  850. printk("unlink busy SCB %lx; ", (ULONG) pCurScb);
  851. #endif
  852. pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy;
  853. while (pTmpScb != NULL) {
  854. if (pCurScb == pTmpScb) { /* Unlink this SCB */
  855. if (pTmpScb == pCurHcb->HCS_FirstBusy) {
  856. if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL)
  857. pCurHcb->HCS_LastBusy = NULL;
  858. } else {
  859. pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
  860. if (pTmpScb == pCurHcb->HCS_LastBusy)
  861. pCurHcb->HCS_LastBusy = pPrevScb;
  862. }
  863. pTmpScb->SCB_NxtScb = NULL;
  864. if (pTmpScb->SCB_TagMsg)
  865. pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--;
  866. else
  867. pCurHcb->HCS_Tcs[pTmpScb->SCB_Target].TCS_Flags &= ~TCF_BUSY;
  868. break;
  869. }
  870. pPrevScb = pTmpScb;
  871. pTmpScb = pTmpScb->SCB_NxtScb;
  872. }
  873. return;
  874. }
  875. /***************************************************************************/
  876. SCB *tul_find_busy_scb(HCS * pCurHcb, WORD tarlun)
  877. {
  878. SCB *pTmpScb, *pPrevScb;
  879. WORD scbp_tarlun;
  880. pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy;
  881. while (pTmpScb != NULL) {
  882. scbp_tarlun = (pTmpScb->SCB_Lun << 8) | (pTmpScb->SCB_Target);
  883. if (scbp_tarlun == tarlun) { /* Unlink this SCB */
  884. break;
  885. }
  886. pPrevScb = pTmpScb;
  887. pTmpScb = pTmpScb->SCB_NxtScb;
  888. }
  889. #if DEBUG_QUEUE
  890. printk("find busy SCB %lx; ", (ULONG) pTmpScb);
  891. #endif
  892. return (pTmpScb);
  893. }
  894. /***************************************************************************/
  895. static void tul_append_done_scb(HCS * pCurHcb, SCB * scbp)
  896. {
  897. #if DEBUG_QUEUE
  898. printk("append done SCB %lx; ", (ULONG) scbp);
  899. #endif
  900. scbp->SCB_Status = SCB_DONE;
  901. scbp->SCB_NxtScb = NULL;
  902. if (pCurHcb->HCS_LastDone != NULL) {
  903. pCurHcb->HCS_LastDone->SCB_NxtScb = scbp;
  904. pCurHcb->HCS_LastDone = scbp;
  905. } else {
  906. pCurHcb->HCS_FirstDone = scbp;
  907. pCurHcb->HCS_LastDone = scbp;
  908. }
  909. }
  910. /***************************************************************************/
  911. SCB *tul_find_done_scb(HCS * pCurHcb)
  912. {
  913. SCB *pTmpScb;
  914. if ((pTmpScb = pCurHcb->HCS_FirstDone) != NULL) {
  915. if ((pCurHcb->HCS_FirstDone = pTmpScb->SCB_NxtScb) == NULL)
  916. pCurHcb->HCS_LastDone = NULL;
  917. pTmpScb->SCB_NxtScb = NULL;
  918. }
  919. #if DEBUG_QUEUE
  920. printk("find done SCB %lx; ", (ULONG) pTmpScb);
  921. #endif
  922. return (pTmpScb);
  923. }
  924. /***************************************************************************/
  925. static int tul_abort_srb(HCS * pCurHcb, struct scsi_cmnd *srbp)
  926. {
  927. ULONG flags;
  928. SCB *pTmpScb, *pPrevScb;
  929. spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
  930. if ((pCurHcb->HCS_Semaph == 0) && (pCurHcb->HCS_ActScb == NULL)) {
  931. TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
  932. /* disable Jasmin SCSI Int */
  933. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  934. tulip_main(pCurHcb);
  935. spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
  936. pCurHcb->HCS_Semaph = 1;
  937. TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
  938. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  939. return SCSI_ABORT_SNOOZE;
  940. }
  941. pPrevScb = pTmpScb = pCurHcb->HCS_FirstPend; /* Check Pend queue */
  942. while (pTmpScb != NULL) {
  943. /* 07/27/98 */
  944. if (pTmpScb->SCB_Srb == srbp) {
  945. if (pTmpScb == pCurHcb->HCS_ActScb) {
  946. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  947. return SCSI_ABORT_BUSY;
  948. } else if (pTmpScb == pCurHcb->HCS_FirstPend) {
  949. if ((pCurHcb->HCS_FirstPend = pTmpScb->SCB_NxtScb) == NULL)
  950. pCurHcb->HCS_LastPend = NULL;
  951. } else {
  952. pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
  953. if (pTmpScb == pCurHcb->HCS_LastPend)
  954. pCurHcb->HCS_LastPend = pPrevScb;
  955. }
  956. pTmpScb->SCB_HaStat = HOST_ABORTED;
  957. pTmpScb->SCB_Flags |= SCF_DONE;
  958. if (pTmpScb->SCB_Flags & SCF_POST)
  959. (*pTmpScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pTmpScb);
  960. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  961. return SCSI_ABORT_SUCCESS;
  962. }
  963. pPrevScb = pTmpScb;
  964. pTmpScb = pTmpScb->SCB_NxtScb;
  965. }
  966. pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy; /* Check Busy queue */
  967. while (pTmpScb != NULL) {
  968. if (pTmpScb->SCB_Srb == srbp) {
  969. if (pTmpScb == pCurHcb->HCS_ActScb) {
  970. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  971. return SCSI_ABORT_BUSY;
  972. } else if (pTmpScb->SCB_TagMsg == 0) {
  973. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  974. return SCSI_ABORT_BUSY;
  975. } else {
  976. pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--;
  977. if (pTmpScb == pCurHcb->HCS_FirstBusy) {
  978. if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL)
  979. pCurHcb->HCS_LastBusy = NULL;
  980. } else {
  981. pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
  982. if (pTmpScb == pCurHcb->HCS_LastBusy)
  983. pCurHcb->HCS_LastBusy = pPrevScb;
  984. }
  985. pTmpScb->SCB_NxtScb = NULL;
  986. pTmpScb->SCB_HaStat = HOST_ABORTED;
  987. pTmpScb->SCB_Flags |= SCF_DONE;
  988. if (pTmpScb->SCB_Flags & SCF_POST)
  989. (*pTmpScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pTmpScb);
  990. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  991. return SCSI_ABORT_SUCCESS;
  992. }
  993. }
  994. pPrevScb = pTmpScb;
  995. pTmpScb = pTmpScb->SCB_NxtScb;
  996. }
  997. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  998. return (SCSI_ABORT_NOT_RUNNING);
  999. }
  1000. /***************************************************************************/
  1001. static int tul_bad_seq(HCS * pCurHcb)
  1002. {
  1003. SCB *pCurScb;
  1004. printk("tul_bad_seg c=%d\n", pCurHcb->HCS_Index);
  1005. if ((pCurScb = pCurHcb->HCS_ActScb) != NULL) {
  1006. tul_unlink_busy_scb(pCurHcb, pCurScb);
  1007. pCurScb->SCB_HaStat = HOST_BAD_PHAS;
  1008. pCurScb->SCB_TaStat = 0;
  1009. tul_append_done_scb(pCurHcb, pCurScb);
  1010. }
  1011. tul_stop_bm(pCurHcb);
  1012. tul_reset_scsi(pCurHcb, 8); /* 7/29/98 */
  1013. return (tul_post_scsi_rst(pCurHcb));
  1014. }
  1015. #if 0
  1016. /************************************************************************/
  1017. static int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb,
  1018. unsigned int target, unsigned int ResetFlags)
  1019. {
  1020. ULONG flags;
  1021. SCB *pScb;
  1022. spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
  1023. if (ResetFlags & SCSI_RESET_ASYNCHRONOUS) {
  1024. if ((pCurHcb->HCS_Semaph == 0) && (pCurHcb->HCS_ActScb == NULL)) {
  1025. TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
  1026. /* disable Jasmin SCSI Int */
  1027. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  1028. tulip_main(pCurHcb);
  1029. spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
  1030. pCurHcb->HCS_Semaph = 1;
  1031. TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
  1032. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  1033. return SCSI_RESET_SNOOZE;
  1034. }
  1035. pScb = pCurHcb->HCS_FirstBusy; /* Check Busy queue */
  1036. while (pScb != NULL) {
  1037. if (pScb->SCB_Srb == pSrb)
  1038. break;
  1039. pScb = pScb->SCB_NxtScb;
  1040. }
  1041. if (pScb == NULL) {
  1042. printk("Unable to Reset - No SCB Found\n");
  1043. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  1044. return SCSI_RESET_NOT_RUNNING;
  1045. }
  1046. }
  1047. if ((pScb = tul_alloc_scb(pCurHcb)) == NULL) {
  1048. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  1049. return SCSI_RESET_NOT_RUNNING;
  1050. }
  1051. pScb->SCB_Opcode = BusDevRst;
  1052. pScb->SCB_Flags = SCF_POST;
  1053. pScb->SCB_Target = target;
  1054. pScb->SCB_Mode = 0;
  1055. pScb->SCB_Srb = NULL;
  1056. if (ResetFlags & SCSI_RESET_SYNCHRONOUS) {
  1057. pScb->SCB_Srb = pSrb;
  1058. }
  1059. tul_push_pend_scb(pCurHcb, pScb); /* push this SCB to Pending queue */
  1060. if (pCurHcb->HCS_Semaph == 1) {
  1061. TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
  1062. /* disable Jasmin SCSI Int */
  1063. pCurHcb->HCS_Semaph = 0;
  1064. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  1065. tulip_main(pCurHcb);
  1066. spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
  1067. pCurHcb->HCS_Semaph = 1;
  1068. TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
  1069. }
  1070. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  1071. return SCSI_RESET_PENDING;
  1072. }
  1073. static int tul_reset_scsi_bus(HCS * pCurHcb)
  1074. {
  1075. ULONG flags;
  1076. spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
  1077. TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
  1078. pCurHcb->HCS_Semaph = 0;
  1079. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  1080. tul_stop_bm(pCurHcb);
  1081. tul_reset_scsi(pCurHcb, 2); /* 7/29/98 */
  1082. spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
  1083. tul_post_scsi_rst(pCurHcb);
  1084. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  1085. tulip_main(pCurHcb);
  1086. spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
  1087. pCurHcb->HCS_Semaph = 1;
  1088. TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
  1089. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  1090. return (SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET);
  1091. }
  1092. #endif /* 0 */
  1093. /************************************************************************/
  1094. static void tul_exec_scb(HCS * pCurHcb, SCB * pCurScb)
  1095. {
  1096. ULONG flags;
  1097. pCurScb->SCB_Mode = 0;
  1098. pCurScb->SCB_SGIdx = 0;
  1099. pCurScb->SCB_SGMax = pCurScb->SCB_SGLen;
  1100. spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
  1101. tul_append_pend_scb(pCurHcb, pCurScb); /* Append this SCB to Pending queue */
  1102. /* VVVVV 07/21/98 */
  1103. if (pCurHcb->HCS_Semaph == 1) {
  1104. TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
  1105. /* disable Jasmin SCSI Int */
  1106. pCurHcb->HCS_Semaph = 0;
  1107. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  1108. tulip_main(pCurHcb);
  1109. spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags);
  1110. pCurHcb->HCS_Semaph = 1;
  1111. TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
  1112. }
  1113. spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags);
  1114. return;
  1115. }
  1116. /***************************************************************************/
  1117. static int tul_isr(HCS * pCurHcb)
  1118. {
  1119. /* Enter critical section */
  1120. if (TUL_RD(pCurHcb->HCS_Base, TUL_Int) & TSS_INT_PENDING) {
  1121. if (pCurHcb->HCS_Semaph == 1) {
  1122. TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F);
  1123. /* Disable Tulip SCSI Int */
  1124. pCurHcb->HCS_Semaph = 0;
  1125. tulip_main(pCurHcb);
  1126. pCurHcb->HCS_Semaph = 1;
  1127. TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F);
  1128. return (1);
  1129. }
  1130. }
  1131. return (0);
  1132. }
  1133. /***************************************************************************/
  1134. int tulip_main(HCS * pCurHcb)
  1135. {
  1136. SCB *pCurScb;
  1137. for (;;) {
  1138. tulip_scsi(pCurHcb); /* Call tulip_scsi */
  1139. while ((pCurScb = tul_find_done_scb(pCurHcb)) != NULL) { /* find done entry */
  1140. if (pCurScb->SCB_TaStat == INI_QUEUE_FULL) {
  1141. pCurHcb->HCS_MaxTags[pCurScb->SCB_Target] =
  1142. pCurHcb->HCS_ActTags[pCurScb->SCB_Target] - 1;
  1143. pCurScb->SCB_TaStat = 0;
  1144. tul_append_pend_scb(pCurHcb, pCurScb);
  1145. continue;
  1146. }
  1147. if (!(pCurScb->SCB_Mode & SCM_RSENS)) { /* not in auto req. sense mode */
  1148. if (pCurScb->SCB_TaStat == 2) {
  1149. /* clr sync. nego flag */
  1150. if (pCurScb->SCB_Flags & SCF_SENSE) {
  1151. BYTE len;
  1152. len = pCurScb->SCB_SenseLen;
  1153. if (len == 0)
  1154. len = 1;
  1155. pCurScb->SCB_BufLen = pCurScb->SCB_SenseLen;
  1156. pCurScb->SCB_BufPtr = pCurScb->SCB_SensePtr;
  1157. pCurScb->SCB_Flags &= ~(SCF_SG | SCF_DIR); /* for xfer_data_in */
  1158. /* pCurScb->SCB_Flags |= SCF_NO_DCHK; */
  1159. /* so, we won't report worng direction in xfer_data_in,
  1160. and won't report HOST_DO_DU in state_6 */
  1161. pCurScb->SCB_Mode = SCM_RSENS;
  1162. pCurScb->SCB_Ident &= 0xBF; /* Disable Disconnect */
  1163. pCurScb->SCB_TagMsg = 0;
  1164. pCurScb->SCB_TaStat = 0;
  1165. pCurScb->SCB_CDBLen = 6;
  1166. pCurScb->SCB_CDB[0] = SCSICMD_RequestSense;
  1167. pCurScb->SCB_CDB[1] = 0;
  1168. pCurScb->SCB_CDB[2] = 0;
  1169. pCurScb->SCB_CDB[3] = 0;
  1170. pCurScb->SCB_CDB[4] = len;
  1171. pCurScb->SCB_CDB[5] = 0;
  1172. tul_push_pend_scb(pCurHcb, pCurScb);
  1173. break;
  1174. }
  1175. }
  1176. } else { /* in request sense mode */
  1177. if (pCurScb->SCB_TaStat == 2) { /* check contition status again after sending
  1178. requset sense cmd 0x3 */
  1179. pCurScb->SCB_HaStat = HOST_BAD_PHAS;
  1180. }
  1181. pCurScb->SCB_TaStat = 2;
  1182. }
  1183. pCurScb->SCB_Flags |= SCF_DONE;
  1184. if (pCurScb->SCB_Flags & SCF_POST) {
  1185. (*pCurScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pCurScb);
  1186. }
  1187. } /* while */
  1188. /* find_active: */
  1189. if (TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0) & TSS_INT_PENDING)
  1190. continue;
  1191. if (pCurHcb->HCS_ActScb) { /* return to OS and wait for xfer_done_ISR/Selected_ISR */
  1192. return 1; /* return to OS, enable interrupt */
  1193. }
  1194. /* Check pending SCB */
  1195. if (tul_find_first_pend_scb(pCurHcb) == NULL) {
  1196. return 1; /* return to OS, enable interrupt */
  1197. }
  1198. } /* End of for loop */
  1199. /* statement won't reach here */
  1200. }
  1201. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
  1202. /***************************************************************************/
  1203. /***************************************************************************/
  1204. /***************************************************************************/
  1205. /***************************************************************************/
  1206. /***************************************************************************/
  1207. void tulip_scsi(HCS * pCurHcb)
  1208. {
  1209. SCB *pCurScb;
  1210. TCS *pCurTcb;
  1211. /* make sure to service interrupt asap */
  1212. if ((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0)) & TSS_INT_PENDING) {
  1213. pCurHcb->HCS_Phase = pCurHcb->HCS_JSStatus0 & TSS_PH_MASK;
  1214. pCurHcb->HCS_JSStatus1 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1);
  1215. pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
  1216. if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) { /* SCSI bus reset detected */
  1217. int_tul_scsi_rst(pCurHcb);
  1218. return;
  1219. }
  1220. if (pCurHcb->HCS_JSInt & TSS_RESEL_INT) { /* if selected/reselected interrupt */
  1221. if (int_tul_resel(pCurHcb) == 0)
  1222. tul_next_state(pCurHcb);
  1223. return;
  1224. }
  1225. if (pCurHcb->HCS_JSInt & TSS_SEL_TIMEOUT) {
  1226. int_tul_busfree(pCurHcb);
  1227. return;
  1228. }
  1229. if (pCurHcb->HCS_JSInt & TSS_DISC_INT) { /* BUS disconnection */
  1230. int_tul_busfree(pCurHcb); /* unexpected bus free or sel timeout */
  1231. return;
  1232. }
  1233. if (pCurHcb->HCS_JSInt & (TSS_FUNC_COMP | TSS_BUS_SERV)) { /* func complete or Bus service */
  1234. if ((pCurScb = pCurHcb->HCS_ActScb) != NULL)
  1235. tul_next_state(pCurHcb);
  1236. return;
  1237. }
  1238. }
  1239. if (pCurHcb->HCS_ActScb != NULL)
  1240. return;
  1241. if ((pCurScb = tul_find_first_pend_scb(pCurHcb)) == NULL)
  1242. return;
  1243. /* program HBA's SCSI ID & target SCSI ID */
  1244. TUL_WR(pCurHcb->HCS_Base + TUL_SScsiId,
  1245. (pCurHcb->HCS_SCSI_ID << 4) | (pCurScb->SCB_Target & 0x0F));
  1246. if (pCurScb->SCB_Opcode == ExecSCSI) {
  1247. pCurTcb = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target];
  1248. if (pCurScb->SCB_TagMsg)
  1249. pCurTcb->TCS_DrvFlags |= TCF_DRV_EN_TAG;
  1250. else
  1251. pCurTcb->TCS_DrvFlags &= ~TCF_DRV_EN_TAG;
  1252. TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurTcb->TCS_JS_Period);
  1253. if ((pCurTcb->TCS_Flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) { /* do wdtr negotiation */
  1254. tul_select_atn_stop(pCurHcb, pCurScb);
  1255. } else {
  1256. if ((pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) { /* do sync negotiation */
  1257. tul_select_atn_stop(pCurHcb, pCurScb);
  1258. } else {
  1259. if (pCurScb->SCB_TagMsg)
  1260. tul_select_atn3(pCurHcb, pCurScb);
  1261. else
  1262. tul_select_atn(pCurHcb, pCurScb);
  1263. }
  1264. }
  1265. if (pCurScb->SCB_Flags & SCF_POLL) {
  1266. while (wait_tulip(pCurHcb) != -1) {
  1267. if (tul_next_state(pCurHcb) == -1)
  1268. break;
  1269. }
  1270. }
  1271. } else if (pCurScb->SCB_Opcode == BusDevRst) {
  1272. tul_select_atn_stop(pCurHcb, pCurScb);
  1273. pCurScb->SCB_NxtStat = 8;
  1274. if (pCurScb->SCB_Flags & SCF_POLL) {
  1275. while (wait_tulip(pCurHcb) != -1) {
  1276. if (tul_next_state(pCurHcb) == -1)
  1277. break;
  1278. }
  1279. }
  1280. } else if (pCurScb->SCB_Opcode == AbortCmd) {
  1281. if (tul_abort_srb(pCurHcb, pCurScb->SCB_Srb) != 0) {
  1282. tul_unlink_pend_scb(pCurHcb, pCurScb);
  1283. tul_release_scb(pCurHcb, pCurScb);
  1284. } else {
  1285. pCurScb->SCB_Opcode = BusDevRst;
  1286. tul_select_atn_stop(pCurHcb, pCurScb);
  1287. pCurScb->SCB_NxtStat = 8;
  1288. }
  1289. /* 08/03/98 */
  1290. } else {
  1291. tul_unlink_pend_scb(pCurHcb, pCurScb);
  1292. pCurScb->SCB_HaStat = 0x16; /* bad command */
  1293. tul_append_done_scb(pCurHcb, pCurScb);
  1294. }
  1295. return;
  1296. }
  1297. /***************************************************************************/
  1298. int tul_next_state(HCS * pCurHcb)
  1299. {
  1300. int next;
  1301. next = pCurHcb->HCS_ActScb->SCB_NxtStat;
  1302. for (;;) {
  1303. switch (next) {
  1304. case 1:
  1305. next = tul_state_1(pCurHcb);
  1306. break;
  1307. case 2:
  1308. next = tul_state_2(pCurHcb);
  1309. break;
  1310. case 3:
  1311. next = tul_state_3(pCurHcb);
  1312. break;
  1313. case 4:
  1314. next = tul_state_4(pCurHcb);
  1315. break;
  1316. case 5:
  1317. next = tul_state_5(pCurHcb);
  1318. break;
  1319. case 6:
  1320. next = tul_state_6(pCurHcb);
  1321. break;
  1322. case 7:
  1323. next = tul_state_7(pCurHcb);
  1324. break;
  1325. case 8:
  1326. return (tul_bus_device_reset(pCurHcb));
  1327. default:
  1328. return (tul_bad_seq(pCurHcb));
  1329. }
  1330. if (next <= 0)
  1331. return next;
  1332. }
  1333. }
  1334. /***************************************************************************/
  1335. /* sTate after selection with attention & stop */
  1336. int tul_state_1(HCS * pCurHcb)
  1337. {
  1338. SCB *pCurScb = pCurHcb->HCS_ActScb;
  1339. TCS *pCurTcb = pCurHcb->HCS_ActTcs;
  1340. #if DEBUG_STATE
  1341. printk("-s1-");
  1342. #endif
  1343. tul_unlink_pend_scb(pCurHcb, pCurScb);
  1344. tul_append_busy_scb(pCurHcb, pCurScb);
  1345. TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurTcb->TCS_SConfig0);
  1346. /* ATN on */
  1347. if (pCurHcb->HCS_Phase == MSG_OUT) {
  1348. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, (TSC_EN_BUS_IN | TSC_HW_RESELECT));
  1349. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_Ident);
  1350. if (pCurScb->SCB_TagMsg) {
  1351. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagMsg);
  1352. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagId);
  1353. }
  1354. if ((pCurTcb->TCS_Flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) {
  1355. pCurTcb->TCS_Flags |= TCF_WDTR_DONE;
  1356. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
  1357. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 2); /* Extended msg length */
  1358. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3); /* Sync request */
  1359. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1); /* Start from 16 bits */
  1360. } else if ((pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) {
  1361. pCurTcb->TCS_Flags |= TCF_SYNC_DONE;
  1362. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
  1363. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3); /* extended msg length */
  1364. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1); /* sync request */
  1365. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, tul_rate_tbl[pCurTcb->TCS_Flags & TCF_SCSI_RATE]);
  1366. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MAX_OFFSET); /* REQ/ACK offset */
  1367. }
  1368. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
  1369. if (wait_tulip(pCurHcb) == -1)
  1370. return (-1);
  1371. }
  1372. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
  1373. TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, (TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)));
  1374. return (3);
  1375. }
  1376. /***************************************************************************/
  1377. /* state after selection with attention */
  1378. /* state after selection with attention3 */
  1379. int tul_state_2(HCS * pCurHcb)
  1380. {
  1381. SCB *pCurScb = pCurHcb->HCS_ActScb;
  1382. TCS *pCurTcb = pCurHcb->HCS_ActTcs;
  1383. #if DEBUG_STATE
  1384. printk("-s2-");
  1385. #endif
  1386. tul_unlink_pend_scb(pCurHcb, pCurScb);
  1387. tul_append_busy_scb(pCurHcb, pCurScb);
  1388. TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurTcb->TCS_SConfig0);
  1389. if (pCurHcb->HCS_JSStatus1 & TSS_CMD_PH_CMP) {
  1390. return (4);
  1391. }
  1392. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
  1393. TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, (TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)));
  1394. return (3);
  1395. }
  1396. /***************************************************************************/
  1397. /* state before CDB xfer is done */
  1398. int tul_state_3(HCS * pCurHcb)
  1399. {
  1400. SCB *pCurScb = pCurHcb->HCS_ActScb;
  1401. TCS *pCurTcb = pCurHcb->HCS_ActTcs;
  1402. int i;
  1403. #if DEBUG_STATE
  1404. printk("-s3-");
  1405. #endif
  1406. for (;;) {
  1407. switch (pCurHcb->HCS_Phase) {
  1408. case CMD_OUT: /* Command out phase */
  1409. for (i = 0; i < (int) pCurScb->SCB_CDBLen; i++)
  1410. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_CDB[i]);
  1411. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
  1412. if (wait_tulip(pCurHcb) == -1)
  1413. return (-1);
  1414. if (pCurHcb->HCS_Phase == CMD_OUT) {
  1415. return (tul_bad_seq(pCurHcb));
  1416. }
  1417. return (4);
  1418. case MSG_IN: /* Message in phase */
  1419. pCurScb->SCB_NxtStat = 3;
  1420. if (tul_msgin(pCurHcb) == -1)
  1421. return (-1);
  1422. break;
  1423. case STATUS_IN: /* Status phase */
  1424. if (tul_status_msg(pCurHcb) == -1)
  1425. return (-1);
  1426. break;
  1427. case MSG_OUT: /* Message out phase */
  1428. if (pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) {
  1429. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP); /* msg nop */
  1430. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
  1431. if (wait_tulip(pCurHcb) == -1)
  1432. return (-1);
  1433. } else {
  1434. pCurTcb->TCS_Flags |= TCF_SYNC_DONE;
  1435. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
  1436. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3); /* ext. msg len */
  1437. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1); /* sync request */
  1438. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, tul_rate_tbl[pCurTcb->TCS_Flags & TCF_SCSI_RATE]);
  1439. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MAX_OFFSET); /* REQ/ACK offset */
  1440. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
  1441. if (wait_tulip(pCurHcb) == -1)
  1442. return (-1);
  1443. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
  1444. TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7));
  1445. }
  1446. break;
  1447. default:
  1448. return (tul_bad_seq(pCurHcb));
  1449. }
  1450. }
  1451. }
  1452. /***************************************************************************/
  1453. int tul_state_4(HCS * pCurHcb)
  1454. {
  1455. SCB *pCurScb = pCurHcb->HCS_ActScb;
  1456. #if DEBUG_STATE
  1457. printk("-s4-");
  1458. #endif
  1459. if ((pCurScb->SCB_Flags & SCF_DIR) == SCF_NO_XF) {
  1460. return (6); /* Go to state 6 */
  1461. }
  1462. for (;;) {
  1463. if (pCurScb->SCB_BufLen == 0)
  1464. return (6); /* Go to state 6 */
  1465. switch (pCurHcb->HCS_Phase) {
  1466. case STATUS_IN: /* Status phase */
  1467. if ((pCurScb->SCB_Flags & SCF_DIR) != 0) { /* if direction bit set then report data underrun */
  1468. pCurScb->SCB_HaStat = HOST_DO_DU;
  1469. }
  1470. if ((tul_status_msg(pCurHcb)) == -1)
  1471. return (-1);
  1472. break;
  1473. case MSG_IN: /* Message in phase */
  1474. pCurScb->SCB_NxtStat = 0x4;
  1475. if (tul_msgin(pCurHcb) == -1)
  1476. return (-1);
  1477. break;
  1478. case MSG_OUT: /* Message out phase */
  1479. if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) {
  1480. pCurScb->SCB_BufLen = 0;
  1481. pCurScb->SCB_HaStat = HOST_DO_DU;
  1482. if (tul_msgout_ide(pCurHcb) == -1)
  1483. return (-1);
  1484. return (6); /* Go to state 6 */
  1485. } else {
  1486. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP); /* msg nop */
  1487. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
  1488. if (wait_tulip(pCurHcb) == -1)
  1489. return (-1);
  1490. }
  1491. break;
  1492. case DATA_IN: /* Data in phase */
  1493. return (tul_xfer_data_in(pCurHcb));
  1494. case DATA_OUT: /* Data out phase */
  1495. return (tul_xfer_data_out(pCurHcb));
  1496. default:
  1497. return (tul_bad_seq(pCurHcb));
  1498. }
  1499. }
  1500. }
  1501. /***************************************************************************/
  1502. /* state after dma xfer done or phase change before xfer done */
  1503. int tul_state_5(HCS * pCurHcb)
  1504. {
  1505. SCB *pCurScb = pCurHcb->HCS_ActScb;
  1506. long cnt, xcnt; /* cannot use unsigned !! code: if (xcnt < 0) */
  1507. #if DEBUG_STATE
  1508. printk("-s5-");
  1509. #endif
  1510. /*------ get remaining count -------*/
  1511. cnt = TUL_RDLONG(pCurHcb->HCS_Base, TUL_SCnt0) & 0x0FFFFFF;
  1512. if (TUL_RD(pCurHcb->HCS_Base, TUL_XCmd) & 0x20) {
  1513. /* ----------------------- DATA_IN ----------------------------- */
  1514. /* check scsi parity error */
  1515. if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) {
  1516. pCurScb->SCB_HaStat = HOST_DO_DU;
  1517. }
  1518. if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) { /* DMA xfer pending, Send STOP */
  1519. /* tell Hardware scsi xfer has been terminated */
  1520. TUL_WR(pCurHcb->HCS_Base + TUL_XCtrl, TUL_RD(pCurHcb->HCS_Base, TUL_XCtrl) | 0x80);
  1521. /* wait until DMA xfer not pending */
  1522. while (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND);
  1523. }
  1524. } else {
  1525. /*-------- DATA OUT -----------*/
  1526. if ((TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1) & TSS_XFER_CMP) == 0) {
  1527. if (pCurHcb->HCS_ActTcs->TCS_JS_Period & TSC_WIDE_SCSI)
  1528. cnt += (TUL_RD(pCurHcb->HCS_Base, TUL_SFifoCnt) & 0x1F) << 1;
  1529. else
  1530. cnt += (TUL_RD(pCurHcb->HCS_Base, TUL_SFifoCnt) & 0x1F);
  1531. }
  1532. if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) { /* if DMA xfer is pending, abort DMA xfer */
  1533. TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_ABT);
  1534. /* wait Abort DMA xfer done */
  1535. while ((TUL_RD(pCurHcb->HCS_Base, TUL_Int) & XABT) == 0);
  1536. }
  1537. if ((cnt == 1) && (pCurHcb->HCS_Phase == DATA_OUT)) {
  1538. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
  1539. if (wait_tulip(pCurHcb) == -1) {
  1540. return (-1);
  1541. }
  1542. cnt = 0;
  1543. } else {
  1544. if ((TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1) & TSS_XFER_CMP) == 0)
  1545. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
  1546. }
  1547. }
  1548. if (cnt == 0) {
  1549. pCurScb->SCB_BufLen = 0;
  1550. return (6); /* Go to state 6 */
  1551. }
  1552. /* Update active data pointer */
  1553. xcnt = (long) pCurScb->SCB_BufLen - cnt; /* xcnt== bytes already xferred */
  1554. pCurScb->SCB_BufLen = (U32) cnt; /* cnt == bytes left to be xferred */
  1555. if (pCurScb->SCB_Flags & SCF_SG) {
  1556. register SG *sgp;
  1557. ULONG i;
  1558. sgp = &pCurScb->SCB_SGList[pCurScb->SCB_SGIdx];
  1559. for (i = pCurScb->SCB_SGIdx; i < pCurScb->SCB_SGMax; sgp++, i++) {
  1560. xcnt -= (long) sgp->SG_Len;
  1561. if (xcnt < 0) { /* this sgp xfer half done */
  1562. xcnt += (long) sgp->SG_Len; /* xcnt == bytes xferred in this sgp */
  1563. sgp->SG_Ptr += (U32) xcnt; /* new ptr to be xfer */
  1564. sgp->SG_Len -= (U32) xcnt; /* new len to be xfer */
  1565. pCurScb->SCB_BufPtr += ((U32) (i - pCurScb->SCB_SGIdx) << 3);
  1566. /* new SG table ptr */
  1567. pCurScb->SCB_SGLen = (BYTE) (pCurScb->SCB_SGMax - i);
  1568. /* new SG table len */
  1569. pCurScb->SCB_SGIdx = (WORD) i;
  1570. /* for next disc and come in this loop */
  1571. return (4); /* Go to state 4 */
  1572. }
  1573. /* else (xcnt >= 0 , i.e. this sgp already xferred */
  1574. } /* for */
  1575. return (6); /* Go to state 6 */
  1576. } else {
  1577. pCurScb->SCB_BufPtr += (U32) xcnt;
  1578. }
  1579. return (4); /* Go to state 4 */
  1580. }
  1581. /***************************************************************************/
  1582. /* state after Data phase */
  1583. int tul_state_6(HCS * pCurHcb)
  1584. {
  1585. SCB *pCurScb = pCurHcb->HCS_ActScb;
  1586. #if DEBUG_STATE
  1587. printk("-s6-");
  1588. #endif
  1589. for (;;) {
  1590. switch (pCurHcb->HCS_Phase) {
  1591. case STATUS_IN: /* Status phase */
  1592. if ((tul_status_msg(pCurHcb)) == -1)
  1593. return (-1);
  1594. break;
  1595. case MSG_IN: /* Message in phase */
  1596. pCurScb->SCB_NxtStat = 6;
  1597. if ((tul_msgin(pCurHcb)) == -1)
  1598. return (-1);
  1599. break;
  1600. case MSG_OUT: /* Message out phase */
  1601. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP); /* msg nop */
  1602. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
  1603. if (wait_tulip(pCurHcb) == -1)
  1604. return (-1);
  1605. break;
  1606. case DATA_IN: /* Data in phase */
  1607. return (tul_xpad_in(pCurHcb));
  1608. case DATA_OUT: /* Data out phase */
  1609. return (tul_xpad_out(pCurHcb));
  1610. default:
  1611. return (tul_bad_seq(pCurHcb));
  1612. }
  1613. }
  1614. }
  1615. /***************************************************************************/
  1616. int tul_state_7(HCS * pCurHcb)
  1617. {
  1618. int cnt, i;
  1619. #if DEBUG_STATE
  1620. printk("-s7-");
  1621. #endif
  1622. /* flush SCSI FIFO */
  1623. cnt = TUL_RD(pCurHcb->HCS_Base, TUL_SFifoCnt) & 0x1F;
  1624. if (cnt) {
  1625. for (i = 0; i < cnt; i++)
  1626. TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
  1627. }
  1628. switch (pCurHcb->HCS_Phase) {
  1629. case DATA_IN: /* Data in phase */
  1630. case DATA_OUT: /* Data out phase */
  1631. return (tul_bad_seq(pCurHcb));
  1632. default:
  1633. return (6); /* Go to state 6 */
  1634. }
  1635. }
  1636. /***************************************************************************/
  1637. int tul_xfer_data_in(HCS * pCurHcb)
  1638. {
  1639. SCB *pCurScb = pCurHcb->HCS_ActScb;
  1640. if ((pCurScb->SCB_Flags & SCF_DIR) == SCF_DOUT) {
  1641. return (6); /* wrong direction */
  1642. }
  1643. TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, pCurScb->SCB_BufLen);
  1644. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_DMA_IN); /* 7/25/95 */
  1645. if (pCurScb->SCB_Flags & SCF_SG) { /* S/G xfer */
  1646. TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, ((ULONG) pCurScb->SCB_SGLen) << 3);
  1647. TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr);
  1648. TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_SG_IN);
  1649. } else {
  1650. TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, pCurScb->SCB_BufLen);
  1651. TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr);
  1652. TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_IN);
  1653. }
  1654. pCurScb->SCB_NxtStat = 0x5;
  1655. return (0); /* return to OS, wait xfer done , let jas_isr come in */
  1656. }
  1657. /***************************************************************************/
  1658. int tul_xfer_data_out(HCS * pCurHcb)
  1659. {
  1660. SCB *pCurScb = pCurHcb->HCS_ActScb;
  1661. if ((pCurScb->SCB_Flags & SCF_DIR) == SCF_DIN) {
  1662. return (6); /* wrong direction */
  1663. }
  1664. TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, pCurScb->SCB_BufLen);
  1665. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_DMA_OUT);
  1666. if (pCurScb->SCB_Flags & SCF_SG) { /* S/G xfer */
  1667. TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, ((ULONG) pCurScb->SCB_SGLen) << 3);
  1668. TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr);
  1669. TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_SG_OUT);
  1670. } else {
  1671. TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, pCurScb->SCB_BufLen);
  1672. TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr);
  1673. TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_OUT);
  1674. }
  1675. pCurScb->SCB_NxtStat = 0x5;
  1676. return (0); /* return to OS, wait xfer done , let jas_isr come in */
  1677. }
  1678. /***************************************************************************/
  1679. int tul_xpad_in(HCS * pCurHcb)
  1680. {
  1681. SCB *pCurScb = pCurHcb->HCS_ActScb;
  1682. TCS *pCurTcb = pCurHcb->HCS_ActTcs;
  1683. if ((pCurScb->SCB_Flags & SCF_DIR) != SCF_NO_DCHK) {
  1684. pCurScb->SCB_HaStat = HOST_DO_DU; /* over run */
  1685. }
  1686. for (;;) {
  1687. if (pCurTcb->TCS_JS_Period & TSC_WIDE_SCSI)
  1688. TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 2);
  1689. else
  1690. TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
  1691. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
  1692. if ((wait_tulip(pCurHcb)) == -1) {
  1693. return (-1);
  1694. }
  1695. if (pCurHcb->HCS_Phase != DATA_IN) {
  1696. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
  1697. return (6);
  1698. }
  1699. TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
  1700. }
  1701. }
  1702. int tul_xpad_out(HCS * pCurHcb)
  1703. {
  1704. SCB *pCurScb = pCurHcb->HCS_ActScb;
  1705. TCS *pCurTcb = pCurHcb->HCS_ActTcs;
  1706. if ((pCurScb->SCB_Flags & SCF_DIR) != SCF_NO_DCHK) {
  1707. pCurScb->SCB_HaStat = HOST_DO_DU; /* over run */
  1708. }
  1709. for (;;) {
  1710. if (pCurTcb->TCS_JS_Period & TSC_WIDE_SCSI)
  1711. TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 2);
  1712. else
  1713. TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
  1714. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 0);
  1715. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
  1716. if ((wait_tulip(pCurHcb)) == -1) {
  1717. return (-1);
  1718. }
  1719. if (pCurHcb->HCS_Phase != DATA_OUT) { /* Disable wide CPU to allow read 16 bits */
  1720. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT);
  1721. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
  1722. return (6);
  1723. }
  1724. }
  1725. }
  1726. /***************************************************************************/
  1727. int tul_status_msg(HCS * pCurHcb)
  1728. { /* status & MSG_IN */
  1729. SCB *pCurScb = pCurHcb->HCS_ActScb;
  1730. BYTE msg;
  1731. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_CMD_COMP);
  1732. if ((wait_tulip(pCurHcb)) == -1) {
  1733. return (-1);
  1734. }
  1735. /* get status */
  1736. pCurScb->SCB_TaStat = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
  1737. if (pCurHcb->HCS_Phase == MSG_OUT) {
  1738. if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) {
  1739. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_PARITY);
  1740. } else {
  1741. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP);
  1742. }
  1743. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
  1744. return (wait_tulip(pCurHcb));
  1745. }
  1746. if (pCurHcb->HCS_Phase == MSG_IN) {
  1747. msg = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
  1748. if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) { /* Parity error */
  1749. if ((tul_msgin_accept(pCurHcb)) == -1)
  1750. return (-1);
  1751. if (pCurHcb->HCS_Phase != MSG_OUT)
  1752. return (tul_bad_seq(pCurHcb));
  1753. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_PARITY);
  1754. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
  1755. return (wait_tulip(pCurHcb));
  1756. }
  1757. if (msg == 0) { /* Command complete */
  1758. if ((pCurScb->SCB_TaStat & 0x18) == 0x10) { /* No link support */
  1759. return (tul_bad_seq(pCurHcb));
  1760. }
  1761. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
  1762. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT);
  1763. return tul_wait_done_disc(pCurHcb);
  1764. }
  1765. if ((msg == MSG_LINK_COMP) || (msg == MSG_LINK_FLAG)) {
  1766. if ((pCurScb->SCB_TaStat & 0x18) == 0x10)
  1767. return (tul_msgin_accept(pCurHcb));
  1768. }
  1769. }
  1770. return (tul_bad_seq(pCurHcb));
  1771. }
  1772. /***************************************************************************/
  1773. /* scsi bus free */
  1774. int int_tul_busfree(HCS * pCurHcb)
  1775. {
  1776. SCB *pCurScb = pCurHcb->HCS_ActScb;
  1777. if (pCurScb != NULL) {
  1778. if (pCurScb->SCB_Status & SCB_SELECT) { /* selection timeout */
  1779. tul_unlink_pend_scb(pCurHcb, pCurScb);
  1780. pCurScb->SCB_HaStat = HOST_SEL_TOUT;
  1781. tul_append_done_scb(pCurHcb, pCurScb);
  1782. } else { /* Unexpected bus free */
  1783. tul_unlink_busy_scb(pCurHcb, pCurScb);
  1784. pCurScb->SCB_HaStat = HOST_BUS_FREE;
  1785. tul_append_done_scb(pCurHcb, pCurScb);
  1786. }
  1787. pCurHcb->HCS_ActScb = NULL;
  1788. pCurHcb->HCS_ActTcs = NULL;
  1789. }
  1790. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); /* Flush SCSI FIFO */
  1791. TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
  1792. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); /* Enable HW reselect */
  1793. return (-1);
  1794. }
  1795. /***************************************************************************/
  1796. /* scsi bus reset */
  1797. static int int_tul_scsi_rst(HCS * pCurHcb)
  1798. {
  1799. SCB *pCurScb;
  1800. int i;
  1801. /* if DMA xfer is pending, abort DMA xfer */
  1802. if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & 0x01) {
  1803. TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_ABT | TAX_X_CLR_FIFO);
  1804. /* wait Abort DMA xfer done */
  1805. while ((TUL_RD(pCurHcb->HCS_Base, TUL_Int) & 0x04) == 0);
  1806. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
  1807. }
  1808. /* Abort all active & disconnected scb */
  1809. while ((pCurScb = tul_pop_busy_scb(pCurHcb)) != NULL) {
  1810. pCurScb->SCB_HaStat = HOST_BAD_PHAS;
  1811. tul_append_done_scb(pCurHcb, pCurScb);
  1812. }
  1813. pCurHcb->HCS_ActScb = NULL;
  1814. pCurHcb->HCS_ActTcs = NULL;
  1815. /* clr sync nego. done flag */
  1816. for (i = 0; i < pCurHcb->HCS_MaxTar; i++) {
  1817. pCurHcb->HCS_Tcs[i].TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
  1818. }
  1819. return (-1);
  1820. }
  1821. /***************************************************************************/
  1822. /* scsi reselection */
  1823. int int_tul_resel(HCS * pCurHcb)
  1824. {
  1825. SCB *pCurScb;
  1826. TCS *pCurTcb;
  1827. BYTE tag, msg = 0;
  1828. BYTE tar, lun;
  1829. if ((pCurScb = pCurHcb->HCS_ActScb) != NULL) {
  1830. if (pCurScb->SCB_Status & SCB_SELECT) { /* if waiting for selection complete */
  1831. pCurScb->SCB_Status &= ~SCB_SELECT;
  1832. }
  1833. pCurHcb->HCS_ActScb = NULL;
  1834. }
  1835. /* --------- get target id---------------------- */
  1836. tar = TUL_RD(pCurHcb->HCS_Base, TUL_SBusId);
  1837. /* ------ get LUN from Identify message----------- */
  1838. lun = TUL_RD(pCurHcb->HCS_Base, TUL_SIdent) & 0x0F;
  1839. /* 07/22/98 from 0x1F -> 0x0F */
  1840. pCurTcb = &pCurHcb->HCS_Tcs[tar];
  1841. pCurHcb->HCS_ActTcs = pCurTcb;
  1842. TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurTcb->TCS_SConfig0);
  1843. TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurTcb->TCS_JS_Period);
  1844. /* ------------- tag queueing ? ------------------- */
  1845. if (pCurTcb->TCS_DrvFlags & TCF_DRV_EN_TAG) {
  1846. if ((tul_msgin_accept(pCurHcb)) == -1)
  1847. return (-1);
  1848. if (pCurHcb->HCS_Phase != MSG_IN)
  1849. goto no_tag;
  1850. TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
  1851. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
  1852. if ((wait_tulip(pCurHcb)) == -1)
  1853. return (-1);
  1854. msg = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); /* Read Tag Message */
  1855. if ((msg < MSG_STAG) || (msg > MSG_OTAG)) /* Is simple Tag */
  1856. goto no_tag;
  1857. if ((tul_msgin_accept(pCurHcb)) == -1)
  1858. return (-1);
  1859. if (pCurHcb->HCS_Phase != MSG_IN)
  1860. goto no_tag;
  1861. TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
  1862. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
  1863. if ((wait_tulip(pCurHcb)) == -1)
  1864. return (-1);
  1865. tag = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); /* Read Tag ID */
  1866. pCurScb = pCurHcb->HCS_Scb + tag;
  1867. if ((pCurScb->SCB_Target != tar) || (pCurScb->SCB_Lun != lun)) {
  1868. return tul_msgout_abort_tag(pCurHcb);
  1869. }
  1870. if (pCurScb->SCB_Status != SCB_BUSY) { /* 03/24/95 */
  1871. return tul_msgout_abort_tag(pCurHcb);
  1872. }
  1873. pCurHcb->HCS_ActScb = pCurScb;
  1874. if ((tul_msgin_accept(pCurHcb)) == -1)
  1875. return (-1);
  1876. } else { /* No tag */
  1877. no_tag:
  1878. if ((pCurScb = tul_find_busy_scb(pCurHcb, tar | (lun << 8))) == NULL) {
  1879. return tul_msgout_abort_targ(pCurHcb);
  1880. }
  1881. pCurHcb->HCS_ActScb = pCurScb;
  1882. if (!(pCurTcb->TCS_DrvFlags & TCF_DRV_EN_TAG)) {
  1883. if ((tul_msgin_accept(pCurHcb)) == -1)
  1884. return (-1);
  1885. }
  1886. }
  1887. return 0;
  1888. }
  1889. /***************************************************************************/
  1890. static int int_tul_bad_seq(HCS * pCurHcb)
  1891. { /* target wrong phase */
  1892. SCB *pCurScb;
  1893. int i;
  1894. tul_reset_scsi(pCurHcb, 10);
  1895. while ((pCurScb = tul_pop_busy_scb(pCurHcb)) != NULL) {
  1896. pCurScb->SCB_HaStat = HOST_BAD_PHAS;
  1897. tul_append_done_scb(pCurHcb, pCurScb);
  1898. }
  1899. for (i = 0; i < pCurHcb->HCS_MaxTar; i++) {
  1900. pCurHcb->HCS_Tcs[i].TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
  1901. }
  1902. return (-1);
  1903. }
  1904. /***************************************************************************/
  1905. int tul_msgout_abort_targ(HCS * pCurHcb)
  1906. {
  1907. TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
  1908. if (tul_msgin_accept(pCurHcb) == -1)
  1909. return (-1);
  1910. if (pCurHcb->HCS_Phase != MSG_OUT)
  1911. return (tul_bad_seq(pCurHcb));
  1912. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_ABORT);
  1913. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
  1914. return tul_wait_disc(pCurHcb);
  1915. }
  1916. /***************************************************************************/
  1917. int tul_msgout_abort_tag(HCS * pCurHcb)
  1918. {
  1919. TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
  1920. if (tul_msgin_accept(pCurHcb) == -1)
  1921. return (-1);
  1922. if (pCurHcb->HCS_Phase != MSG_OUT)
  1923. return (tul_bad_seq(pCurHcb));
  1924. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_ABORT_TAG);
  1925. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
  1926. return tul_wait_disc(pCurHcb);
  1927. }
  1928. /***************************************************************************/
  1929. int tul_msgin(HCS * pCurHcb)
  1930. {
  1931. TCS *pCurTcb;
  1932. for (;;) {
  1933. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
  1934. TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
  1935. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
  1936. if ((wait_tulip(pCurHcb)) == -1)
  1937. return (-1);
  1938. switch (TUL_RD(pCurHcb->HCS_Base, TUL_SFifo)) {
  1939. case MSG_DISC: /* Disconnect msg */
  1940. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT);
  1941. return tul_wait_disc(pCurHcb);
  1942. case MSG_SDP:
  1943. case MSG_RESTORE:
  1944. case MSG_NOP:
  1945. tul_msgin_accept(pCurHcb);
  1946. break;
  1947. case MSG_REJ: /* Clear ATN first */
  1948. TUL_WR(pCurHcb->HCS_Base + TUL_SSignal,
  1949. (TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)));
  1950. pCurTcb = pCurHcb->HCS_ActTcs;
  1951. if ((pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) { /* do sync nego */
  1952. TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
  1953. }
  1954. tul_msgin_accept(pCurHcb);
  1955. break;
  1956. case MSG_EXTEND: /* extended msg */
  1957. tul_msgin_extend(pCurHcb);
  1958. break;
  1959. case MSG_IGNOREWIDE:
  1960. tul_msgin_accept(pCurHcb);
  1961. break;
  1962. /* get */
  1963. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
  1964. if (wait_tulip(pCurHcb) == -1)
  1965. return -1;
  1966. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 0); /* put pad */
  1967. TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); /* get IGNORE field */
  1968. TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); /* get pad */
  1969. tul_msgin_accept(pCurHcb);
  1970. break;
  1971. case MSG_COMP:
  1972. {
  1973. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
  1974. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT);
  1975. return tul_wait_done_disc(pCurHcb);
  1976. }
  1977. default:
  1978. tul_msgout_reject(pCurHcb);
  1979. break;
  1980. }
  1981. if (pCurHcb->HCS_Phase != MSG_IN)
  1982. return (pCurHcb->HCS_Phase);
  1983. }
  1984. /* statement won't reach here */
  1985. }
  1986. /***************************************************************************/
  1987. int tul_msgout_reject(HCS * pCurHcb)
  1988. {
  1989. TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
  1990. if ((tul_msgin_accept(pCurHcb)) == -1)
  1991. return (-1);
  1992. if (pCurHcb->HCS_Phase == MSG_OUT) {
  1993. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_REJ); /* Msg reject */
  1994. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
  1995. return (wait_tulip(pCurHcb));
  1996. }
  1997. return (pCurHcb->HCS_Phase);
  1998. }
  1999. /***************************************************************************/
  2000. int tul_msgout_ide(HCS * pCurHcb)
  2001. {
  2002. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_IDE); /* Initiator Detected Error */
  2003. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
  2004. return (wait_tulip(pCurHcb));
  2005. }
  2006. /***************************************************************************/
  2007. int tul_msgin_extend(HCS * pCurHcb)
  2008. {
  2009. BYTE len, idx;
  2010. if (tul_msgin_accept(pCurHcb) != MSG_IN)
  2011. return (pCurHcb->HCS_Phase);
  2012. /* Get extended msg length */
  2013. TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
  2014. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
  2015. if (wait_tulip(pCurHcb) == -1)
  2016. return (-1);
  2017. len = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
  2018. pCurHcb->HCS_Msg[0] = len;
  2019. for (idx = 1; len != 0; len--) {
  2020. if ((tul_msgin_accept(pCurHcb)) != MSG_IN)
  2021. return (pCurHcb->HCS_Phase);
  2022. TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1);
  2023. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN);
  2024. if (wait_tulip(pCurHcb) == -1)
  2025. return (-1);
  2026. pCurHcb->HCS_Msg[idx++] = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo);
  2027. }
  2028. if (pCurHcb->HCS_Msg[1] == 1) { /* if it's synchronous data transfer request */
  2029. if (pCurHcb->HCS_Msg[0] != 3) /* if length is not right */
  2030. return (tul_msgout_reject(pCurHcb));
  2031. if (pCurHcb->HCS_ActTcs->TCS_Flags & TCF_NO_SYNC_NEGO) { /* Set OFFSET=0 to do async, nego back */
  2032. pCurHcb->HCS_Msg[3] = 0;
  2033. } else {
  2034. if ((tul_msgin_sync(pCurHcb) == 0) &&
  2035. (pCurHcb->HCS_ActTcs->TCS_Flags & TCF_SYNC_DONE)) {
  2036. tul_sync_done(pCurHcb);
  2037. return (tul_msgin_accept(pCurHcb));
  2038. }
  2039. }
  2040. TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
  2041. if ((tul_msgin_accept(pCurHcb)) != MSG_OUT)
  2042. return (pCurHcb->HCS_Phase);
  2043. /* sync msg out */
  2044. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO);
  2045. tul_sync_done(pCurHcb);
  2046. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
  2047. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3);
  2048. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1);
  2049. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurHcb->HCS_Msg[2]);
  2050. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurHcb->HCS_Msg[3]);
  2051. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
  2052. return (wait_tulip(pCurHcb));
  2053. }
  2054. if ((pCurHcb->HCS_Msg[0] != 2) || (pCurHcb->HCS_Msg[1] != 3))
  2055. return (tul_msgout_reject(pCurHcb));
  2056. /* if it's WIDE DATA XFER REQ */
  2057. if (pCurHcb->HCS_ActTcs->TCS_Flags & TCF_NO_WDTR) {
  2058. pCurHcb->HCS_Msg[2] = 0;
  2059. } else {
  2060. if (pCurHcb->HCS_Msg[2] > 2) /* > 32 bits */
  2061. return (tul_msgout_reject(pCurHcb));
  2062. if (pCurHcb->HCS_Msg[2] == 2) { /* == 32 */
  2063. pCurHcb->HCS_Msg[2] = 1;
  2064. } else {
  2065. if ((pCurHcb->HCS_ActTcs->TCS_Flags & TCF_NO_WDTR) == 0) {
  2066. wdtr_done(pCurHcb);
  2067. if ((pCurHcb->HCS_ActTcs->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0)
  2068. TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
  2069. return (tul_msgin_accept(pCurHcb));
  2070. }
  2071. }
  2072. }
  2073. TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN));
  2074. if (tul_msgin_accept(pCurHcb) != MSG_OUT)
  2075. return (pCurHcb->HCS_Phase);
  2076. /* WDTR msg out */
  2077. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND);
  2078. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 2);
  2079. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3);
  2080. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurHcb->HCS_Msg[2]);
  2081. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
  2082. return (wait_tulip(pCurHcb));
  2083. }
  2084. /***************************************************************************/
  2085. int tul_msgin_sync(HCS * pCurHcb)
  2086. {
  2087. char default_period;
  2088. default_period = tul_rate_tbl[pCurHcb->HCS_ActTcs->TCS_Flags & TCF_SCSI_RATE];
  2089. if (pCurHcb->HCS_Msg[3] > MAX_OFFSET) {
  2090. pCurHcb->HCS_Msg[3] = MAX_OFFSET;
  2091. if (pCurHcb->HCS_Msg[2] < default_period) {
  2092. pCurHcb->HCS_Msg[2] = default_period;
  2093. return 1;
  2094. }
  2095. if (pCurHcb->HCS_Msg[2] >= 59) { /* Change to async */
  2096. pCurHcb->HCS_Msg[3] = 0;
  2097. }
  2098. return 1;
  2099. }
  2100. /* offset requests asynchronous transfers ? */
  2101. if (pCurHcb->HCS_Msg[3] == 0) {
  2102. return 0;
  2103. }
  2104. if (pCurHcb->HCS_Msg[2] < default_period) {
  2105. pCurHcb->HCS_Msg[2] = default_period;
  2106. return 1;
  2107. }
  2108. if (pCurHcb->HCS_Msg[2] >= 59) {
  2109. pCurHcb->HCS_Msg[3] = 0;
  2110. return 1;
  2111. }
  2112. return 0;
  2113. }
  2114. /***************************************************************************/
  2115. int wdtr_done(HCS * pCurHcb)
  2116. {
  2117. pCurHcb->HCS_ActTcs->TCS_Flags &= ~TCF_SYNC_DONE;
  2118. pCurHcb->HCS_ActTcs->TCS_Flags |= TCF_WDTR_DONE;
  2119. pCurHcb->HCS_ActTcs->TCS_JS_Period = 0;
  2120. if (pCurHcb->HCS_Msg[2]) { /* if 16 bit */
  2121. pCurHcb->HCS_ActTcs->TCS_JS_Period |= TSC_WIDE_SCSI;
  2122. }
  2123. pCurHcb->HCS_ActTcs->TCS_SConfig0 &= ~TSC_ALT_PERIOD;
  2124. TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurHcb->HCS_ActTcs->TCS_SConfig0);
  2125. TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurHcb->HCS_ActTcs->TCS_JS_Period);
  2126. return 1;
  2127. }
  2128. /***************************************************************************/
  2129. int tul_sync_done(HCS * pCurHcb)
  2130. {
  2131. int i;
  2132. pCurHcb->HCS_ActTcs->TCS_Flags |= TCF_SYNC_DONE;
  2133. if (pCurHcb->HCS_Msg[3]) {
  2134. pCurHcb->HCS_ActTcs->TCS_JS_Period |= pCurHcb->HCS_Msg[3];
  2135. for (i = 0; i < 8; i++) {
  2136. if (tul_rate_tbl[i] >= pCurHcb->HCS_Msg[2]) /* pick the big one */
  2137. break;
  2138. }
  2139. pCurHcb->HCS_ActTcs->TCS_JS_Period |= (i << 4);
  2140. pCurHcb->HCS_ActTcs->TCS_SConfig0 |= TSC_ALT_PERIOD;
  2141. }
  2142. TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurHcb->HCS_ActTcs->TCS_SConfig0);
  2143. TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurHcb->HCS_ActTcs->TCS_JS_Period);
  2144. return (-1);
  2145. }
  2146. int tul_post_scsi_rst(HCS * pCurHcb)
  2147. {
  2148. SCB *pCurScb;
  2149. TCS *pCurTcb;
  2150. int i;
  2151. pCurHcb->HCS_ActScb = NULL;
  2152. pCurHcb->HCS_ActTcs = NULL;
  2153. pCurHcb->HCS_Flags = 0;
  2154. while ((pCurScb = tul_pop_busy_scb(pCurHcb)) != NULL) {
  2155. pCurScb->SCB_HaStat = HOST_BAD_PHAS;
  2156. tul_append_done_scb(pCurHcb, pCurScb);
  2157. }
  2158. /* clear sync done flag */
  2159. pCurTcb = &pCurHcb->HCS_Tcs[0];
  2160. for (i = 0; i < pCurHcb->HCS_MaxTar; pCurTcb++, i++) {
  2161. pCurTcb->TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE);
  2162. /* Initialize the sync. xfer register values to an asyn xfer */
  2163. pCurTcb->TCS_JS_Period = 0;
  2164. pCurTcb->TCS_SConfig0 = pCurHcb->HCS_SConf1;
  2165. pCurHcb->HCS_ActTags[0] = 0; /* 07/22/98 */
  2166. pCurHcb->HCS_Tcs[i].TCS_Flags &= ~TCF_BUSY; /* 07/22/98 */
  2167. } /* for */
  2168. return (-1);
  2169. }
  2170. /***************************************************************************/
  2171. void tul_select_atn_stop(HCS * pCurHcb, SCB * pCurScb)
  2172. {
  2173. pCurScb->SCB_Status |= SCB_SELECT;
  2174. pCurScb->SCB_NxtStat = 0x1;
  2175. pCurHcb->HCS_ActScb = pCurScb;
  2176. pCurHcb->HCS_ActTcs = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target];
  2177. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_SELATNSTOP);
  2178. return;
  2179. }
  2180. /***************************************************************************/
  2181. void tul_select_atn(HCS * pCurHcb, SCB * pCurScb)
  2182. {
  2183. int i;
  2184. pCurScb->SCB_Status |= SCB_SELECT;
  2185. pCurScb->SCB_NxtStat = 0x2;
  2186. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_Ident);
  2187. for (i = 0; i < (int) pCurScb->SCB_CDBLen; i++)
  2188. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_CDB[i]);
  2189. pCurHcb->HCS_ActTcs = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target];
  2190. pCurHcb->HCS_ActScb = pCurScb;
  2191. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_SEL_ATN);
  2192. return;
  2193. }
  2194. /***************************************************************************/
  2195. void tul_select_atn3(HCS * pCurHcb, SCB * pCurScb)
  2196. {
  2197. int i;
  2198. pCurScb->SCB_Status |= SCB_SELECT;
  2199. pCurScb->SCB_NxtStat = 0x2;
  2200. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_Ident);
  2201. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagMsg);
  2202. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagId);
  2203. for (i = 0; i < (int) pCurScb->SCB_CDBLen; i++)
  2204. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_CDB[i]);
  2205. pCurHcb->HCS_ActTcs = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target];
  2206. pCurHcb->HCS_ActScb = pCurScb;
  2207. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_SEL_ATN3);
  2208. return;
  2209. }
  2210. /***************************************************************************/
  2211. /* SCSI Bus Device Reset */
  2212. int tul_bus_device_reset(HCS * pCurHcb)
  2213. {
  2214. SCB *pCurScb = pCurHcb->HCS_ActScb;
  2215. TCS *pCurTcb = pCurHcb->HCS_ActTcs;
  2216. SCB *pTmpScb, *pPrevScb;
  2217. BYTE tar;
  2218. if (pCurHcb->HCS_Phase != MSG_OUT) {
  2219. return (int_tul_bad_seq(pCurHcb)); /* Unexpected phase */
  2220. }
  2221. tul_unlink_pend_scb(pCurHcb, pCurScb);
  2222. tul_release_scb(pCurHcb, pCurScb);
  2223. tar = pCurScb->SCB_Target; /* target */
  2224. pCurTcb->TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE | TCF_BUSY);
  2225. /* clr sync. nego & WDTR flags 07/22/98 */
  2226. /* abort all SCB with same target */
  2227. pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy; /* Check Busy queue */
  2228. while (pTmpScb != NULL) {
  2229. if (pTmpScb->SCB_Target == tar) {
  2230. /* unlink it */
  2231. if (pTmpScb == pCurHcb->HCS_FirstBusy) {
  2232. if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL)
  2233. pCurHcb->HCS_LastBusy = NULL;
  2234. } else {
  2235. pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb;
  2236. if (pTmpScb == pCurHcb->HCS_LastBusy)
  2237. pCurHcb->HCS_LastBusy = pPrevScb;
  2238. }
  2239. pTmpScb->SCB_HaStat = HOST_ABORTED;
  2240. tul_append_done_scb(pCurHcb, pTmpScb);
  2241. }
  2242. /* Previous haven't change */
  2243. else {
  2244. pPrevScb = pTmpScb;
  2245. }
  2246. pTmpScb = pTmpScb->SCB_NxtScb;
  2247. }
  2248. TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_DEVRST);
  2249. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT);
  2250. return tul_wait_disc(pCurHcb);
  2251. }
  2252. /***************************************************************************/
  2253. int tul_msgin_accept(HCS * pCurHcb)
  2254. {
  2255. TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT);
  2256. return (wait_tulip(pCurHcb));
  2257. }
  2258. /***************************************************************************/
  2259. int wait_tulip(HCS * pCurHcb)
  2260. {
  2261. while (!((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0))
  2262. & TSS_INT_PENDING));
  2263. pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
  2264. pCurHcb->HCS_Phase = pCurHcb->HCS_JSStatus0 & TSS_PH_MASK;
  2265. pCurHcb->HCS_JSStatus1 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1);
  2266. if (pCurHcb->HCS_JSInt & TSS_RESEL_INT) { /* if SCSI bus reset detected */
  2267. return (int_tul_resel(pCurHcb));
  2268. }
  2269. if (pCurHcb->HCS_JSInt & TSS_SEL_TIMEOUT) { /* if selected/reselected timeout interrupt */
  2270. return (int_tul_busfree(pCurHcb));
  2271. }
  2272. if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) { /* if SCSI bus reset detected */
  2273. return (int_tul_scsi_rst(pCurHcb));
  2274. }
  2275. if (pCurHcb->HCS_JSInt & TSS_DISC_INT) { /* BUS disconnection */
  2276. if (pCurHcb->HCS_Flags & HCF_EXPECT_DONE_DISC) {
  2277. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); /* Flush SCSI FIFO */
  2278. tul_unlink_busy_scb(pCurHcb, pCurHcb->HCS_ActScb);
  2279. pCurHcb->HCS_ActScb->SCB_HaStat = 0;
  2280. tul_append_done_scb(pCurHcb, pCurHcb->HCS_ActScb);
  2281. pCurHcb->HCS_ActScb = NULL;
  2282. pCurHcb->HCS_ActTcs = NULL;
  2283. pCurHcb->HCS_Flags &= ~HCF_EXPECT_DONE_DISC;
  2284. TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
  2285. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); /* Enable HW reselect */
  2286. return (-1);
  2287. }
  2288. if (pCurHcb->HCS_Flags & HCF_EXPECT_DISC) {
  2289. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); /* Flush SCSI FIFO */
  2290. pCurHcb->HCS_ActScb = NULL;
  2291. pCurHcb->HCS_ActTcs = NULL;
  2292. pCurHcb->HCS_Flags &= ~HCF_EXPECT_DISC;
  2293. TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
  2294. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); /* Enable HW reselect */
  2295. return (-1);
  2296. }
  2297. return (int_tul_busfree(pCurHcb));
  2298. }
  2299. if (pCurHcb->HCS_JSInt & (TSS_FUNC_COMP | TSS_BUS_SERV)) {
  2300. return (pCurHcb->HCS_Phase);
  2301. }
  2302. return (pCurHcb->HCS_Phase);
  2303. }
  2304. /***************************************************************************/
  2305. int tul_wait_disc(HCS * pCurHcb)
  2306. {
  2307. while (!((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0))
  2308. & TSS_INT_PENDING));
  2309. pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
  2310. if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) { /* if SCSI bus reset detected */
  2311. return (int_tul_scsi_rst(pCurHcb));
  2312. }
  2313. if (pCurHcb->HCS_JSInt & TSS_DISC_INT) { /* BUS disconnection */
  2314. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); /* Flush SCSI FIFO */
  2315. TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
  2316. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); /* Enable HW reselect */
  2317. pCurHcb->HCS_ActScb = NULL;
  2318. return (-1);
  2319. }
  2320. return (tul_bad_seq(pCurHcb));
  2321. }
  2322. /***************************************************************************/
  2323. int tul_wait_done_disc(HCS * pCurHcb)
  2324. {
  2325. while (!((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0))
  2326. & TSS_INT_PENDING));
  2327. pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt);
  2328. if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) { /* if SCSI bus reset detected */
  2329. return (int_tul_scsi_rst(pCurHcb));
  2330. }
  2331. if (pCurHcb->HCS_JSInt & TSS_DISC_INT) { /* BUS disconnection */
  2332. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); /* Flush SCSI FIFO */
  2333. TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT);
  2334. TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); /* Enable HW reselect */
  2335. tul_unlink_busy_scb(pCurHcb, pCurHcb->HCS_ActScb);
  2336. tul_append_done_scb(pCurHcb, pCurHcb->HCS_ActScb);
  2337. pCurHcb->HCS_ActScb = NULL;
  2338. return (-1);
  2339. }
  2340. return (tul_bad_seq(pCurHcb));
  2341. }
  2342. static irqreturn_t i91u_intr(int irqno, void *dev_id)
  2343. {
  2344. struct Scsi_Host *dev = dev_id;
  2345. unsigned long flags;
  2346. spin_lock_irqsave(dev->host_lock, flags);
  2347. tul_isr((HCS *)dev->base);
  2348. spin_unlock_irqrestore(dev->host_lock, flags);
  2349. return IRQ_HANDLED;
  2350. }
  2351. static int tul_NewReturnNumberOfAdapters(void)
  2352. {
  2353. struct pci_dev *pDev = NULL; /* Start from none */
  2354. int iAdapters = 0;
  2355. long dRegValue;
  2356. WORD wBIOS;
  2357. int i = 0;
  2358. init_i91uAdapter_table();
  2359. for (i = 0; i < ARRAY_SIZE(i91u_pci_devices); i++)
  2360. {
  2361. while ((pDev = pci_find_device(i91u_pci_devices[i].vendor, i91u_pci_devices[i].device, pDev)) != NULL) {
  2362. if (pci_enable_device(pDev))
  2363. continue;
  2364. pci_read_config_dword(pDev, 0x44, (u32 *) & dRegValue);
  2365. wBIOS = (UWORD) (dRegValue & 0xFF);
  2366. if (((dRegValue & 0xFF00) >> 8) == 0xFF)
  2367. dRegValue = 0;
  2368. wBIOS = (wBIOS << 8) + ((UWORD) ((dRegValue & 0xFF00) >> 8));
  2369. if (pci_set_dma_mask(pDev, DMA_32BIT_MASK)) {
  2370. printk(KERN_WARNING
  2371. "i91u: Could not set 32 bit DMA mask\n");
  2372. continue;
  2373. }
  2374. if (Addi91u_into_Adapter_table(wBIOS,
  2375. (pDev->resource[0].start),
  2376. pDev->irq,
  2377. pDev->bus->number,
  2378. (pDev->devfn >> 3)
  2379. ) == 0)
  2380. iAdapters++;
  2381. }
  2382. }
  2383. return (iAdapters);
  2384. }
  2385. static int i91u_detect(struct scsi_host_template * tpnt)
  2386. {
  2387. HCS *pHCB;
  2388. struct Scsi_Host *hreg;
  2389. unsigned long i; /* 01/14/98 */
  2390. int ok = 0, iAdapters;
  2391. ULONG dBiosAdr;
  2392. BYTE *pbBiosAdr;
  2393. /* Get total number of adapters in the motherboard */
  2394. iAdapters = tul_NewReturnNumberOfAdapters();
  2395. if (iAdapters == 0) /* If no tulip founded, return */
  2396. return (0);
  2397. tul_num_ch = (iAdapters > tul_num_ch) ? tul_num_ch : iAdapters;
  2398. /* Update actually channel number */
  2399. if (tul_tag_enable) { /* 1.01i */
  2400. tul_num_scb = MAX_TARGETS * i91u_MAXQUEUE;
  2401. } else {
  2402. tul_num_scb = MAX_TARGETS + 3; /* 1-tape, 1-CD_ROM, 1- extra */
  2403. } /* Update actually SCBs per adapter */
  2404. /* Get total memory needed for HCS */
  2405. i = tul_num_ch * sizeof(HCS);
  2406. memset((unsigned char *) &tul_hcs[0], 0, i); /* Initialize tul_hcs 0 */
  2407. /* Get total memory needed for SCB */
  2408. for (; tul_num_scb >= MAX_TARGETS + 3; tul_num_scb--) {
  2409. i = tul_num_ch * tul_num_scb * sizeof(SCB);
  2410. if ((tul_scb = kmalloc(i, GFP_ATOMIC | GFP_DMA)) != NULL)
  2411. break;
  2412. }
  2413. if (tul_scb == NULL) {
  2414. printk("i91u: SCB memory allocation error\n");
  2415. return (0);
  2416. }
  2417. memset((unsigned char *) tul_scb, 0, i);
  2418. for (i = 0, pHCB = &tul_hcs[0]; /* Get pointer for control block */
  2419. i < tul_num_ch;
  2420. i++, pHCB++) {
  2421. get_tulipPCIConfig(pHCB, i);
  2422. dBiosAdr = pHCB->HCS_BIOS;
  2423. dBiosAdr = (dBiosAdr << 4);
  2424. pbBiosAdr = phys_to_virt(dBiosAdr);
  2425. init_tulip(pHCB, tul_scb + (i * tul_num_scb), tul_num_scb, pbBiosAdr, 10);
  2426. request_region(pHCB->HCS_Base, 256, "i91u"); /* Register */
  2427. pHCB->HCS_Index = i; /* 7/29/98 */
  2428. hreg = scsi_register(tpnt, sizeof(HCS));
  2429. if(hreg == NULL) {
  2430. release_region(pHCB->HCS_Base, 256);
  2431. return 0;
  2432. }
  2433. hreg->io_port = pHCB->HCS_Base;
  2434. hreg->n_io_port = 0xff;
  2435. hreg->can_queue = tul_num_scb; /* 03/05/98 */
  2436. hreg->unique_id = pHCB->HCS_Base;
  2437. hreg->max_id = pHCB->HCS_MaxTar;
  2438. hreg->max_lun = 32; /* 10/21/97 */
  2439. hreg->irq = pHCB->HCS_Intr;
  2440. hreg->this_id = pHCB->HCS_SCSI_ID; /* Assign HCS index */
  2441. hreg->base = (unsigned long)pHCB;
  2442. hreg->sg_tablesize = TOTAL_SG_ENTRY; /* Maximun support is 32 */
  2443. /* Initial tulip chip */
  2444. ok = request_irq(pHCB->HCS_Intr, i91u_intr, IRQF_DISABLED | IRQF_SHARED, "i91u", hreg);
  2445. if (ok < 0) {
  2446. printk(KERN_WARNING "i91u: unable to request IRQ %d\n\n", pHCB->HCS_Intr);
  2447. return 0;
  2448. }
  2449. }
  2450. tpnt->this_id = -1;
  2451. tpnt->can_queue = 1;
  2452. return 1;
  2453. }
  2454. static void i91uBuildSCB(HCS * pHCB, SCB * pSCB, struct scsi_cmnd * SCpnt)
  2455. { /* Create corresponding SCB */
  2456. struct scatterlist *pSrbSG;
  2457. SG *pSG; /* Pointer to SG list */
  2458. int i;
  2459. long TotalLen;
  2460. dma_addr_t dma_addr;
  2461. pSCB->SCB_Post = i91uSCBPost; /* i91u's callback routine */
  2462. pSCB->SCB_Srb = SCpnt;
  2463. pSCB->SCB_Opcode = ExecSCSI;
  2464. pSCB->SCB_Flags = SCF_POST; /* After SCSI done, call post routine */
  2465. pSCB->SCB_Target = SCpnt->device->id;
  2466. pSCB->SCB_Lun = SCpnt->device->lun;
  2467. pSCB->SCB_Ident = SCpnt->device->lun | DISC_ALLOW;
  2468. pSCB->SCB_Flags |= SCF_SENSE; /* Turn on auto request sense */
  2469. dma_addr = dma_map_single(&pHCB->pci_dev->dev, SCpnt->sense_buffer,
  2470. SENSE_SIZE, DMA_FROM_DEVICE);
  2471. pSCB->SCB_SensePtr = cpu_to_le32((u32)dma_addr);
  2472. pSCB->SCB_SenseLen = cpu_to_le32(SENSE_SIZE);
  2473. SCpnt->SCp.ptr = (char *)(unsigned long)dma_addr;
  2474. pSCB->SCB_CDBLen = SCpnt->cmd_len;
  2475. pSCB->SCB_HaStat = 0;
  2476. pSCB->SCB_TaStat = 0;
  2477. memcpy(&pSCB->SCB_CDB[0], &SCpnt->cmnd, SCpnt->cmd_len);
  2478. if (SCpnt->device->tagged_supported) { /* Tag Support */
  2479. pSCB->SCB_TagMsg = SIMPLE_QUEUE_TAG; /* Do simple tag only */
  2480. } else {
  2481. pSCB->SCB_TagMsg = 0; /* No tag support */
  2482. }
  2483. /* todo handle map_sg error */
  2484. if (SCpnt->use_sg) {
  2485. dma_addr = dma_map_single(&pHCB->pci_dev->dev, &pSCB->SCB_SGList[0],
  2486. sizeof(struct SG_Struc) * TOTAL_SG_ENTRY,
  2487. DMA_BIDIRECTIONAL);
  2488. pSCB->SCB_BufPtr = cpu_to_le32((u32)dma_addr);
  2489. SCpnt->SCp.dma_handle = dma_addr;
  2490. pSrbSG = (struct scatterlist *) SCpnt->request_buffer;
  2491. pSCB->SCB_SGLen = dma_map_sg(&pHCB->pci_dev->dev, pSrbSG,
  2492. SCpnt->use_sg, SCpnt->sc_data_direction);
  2493. pSCB->SCB_Flags |= SCF_SG; /* Turn on SG list flag */
  2494. for (i = 0, TotalLen = 0, pSG = &pSCB->SCB_SGList[0]; /* 1.01g */
  2495. i < pSCB->SCB_SGLen; i++, pSG++, pSrbSG++) {
  2496. pSG->SG_Ptr = cpu_to_le32((u32)sg_dma_address(pSrbSG));
  2497. TotalLen += pSG->SG_Len = cpu_to_le32((u32)sg_dma_len(pSrbSG));
  2498. }
  2499. pSCB->SCB_BufLen = (SCpnt->request_bufflen > TotalLen) ?
  2500. TotalLen : SCpnt->request_bufflen;
  2501. } else if (SCpnt->request_bufflen) { /* Non SG */
  2502. dma_addr = dma_map_single(&pHCB->pci_dev->dev, SCpnt->request_buffer,
  2503. SCpnt->request_bufflen,
  2504. SCpnt->sc_data_direction);
  2505. SCpnt->SCp.dma_handle = dma_addr;
  2506. pSCB->SCB_BufPtr = cpu_to_le32((u32)dma_addr);
  2507. pSCB->SCB_BufLen = cpu_to_le32((u32)SCpnt->request_bufflen);
  2508. pSCB->SCB_SGLen = 0;
  2509. } else {
  2510. pSCB->SCB_BufLen = 0;
  2511. pSCB->SCB_SGLen = 0;
  2512. }
  2513. }
  2514. static int i91u_queuecommand(struct scsi_cmnd *cmd,
  2515. void (*done)(struct scsi_cmnd *))
  2516. {
  2517. HCS *pHCB = (HCS *) cmd->device->host->base;
  2518. register SCB *pSCB;
  2519. cmd->scsi_done = done;
  2520. pSCB = tul_alloc_scb(pHCB);
  2521. if (!pSCB)
  2522. return SCSI_MLQUEUE_HOST_BUSY;
  2523. i91uBuildSCB(pHCB, pSCB, cmd);
  2524. tul_exec_scb(pHCB, pSCB);
  2525. return 0;
  2526. }
  2527. #if 0 /* no new EH yet */
  2528. /*
  2529. * Abort a queued command
  2530. * (commands that are on the bus can't be aborted easily)
  2531. */
  2532. static int i91u_abort(struct scsi_cmnd * SCpnt)
  2533. {
  2534. HCS *pHCB;
  2535. pHCB = (HCS *) SCpnt->device->host->base;
  2536. return tul_abort_srb(pHCB, SCpnt);
  2537. }
  2538. /*
  2539. * Reset registers, reset a hanging bus and
  2540. * kill active and disconnected commands for target w/o soft reset
  2541. */
  2542. static int i91u_reset(struct scsi_cmnd * SCpnt, unsigned int reset_flags)
  2543. { /* I need Host Control Block Information */
  2544. HCS *pHCB;
  2545. pHCB = (HCS *) SCpnt->device->host->base;
  2546. if (reset_flags & (SCSI_RESET_SUGGEST_BUS_RESET | SCSI_RESET_SUGGEST_HOST_RESET))
  2547. return tul_reset_scsi_bus(pHCB);
  2548. else
  2549. return tul_device_reset(pHCB, SCpnt, SCpnt->device->id, reset_flags);
  2550. }
  2551. #endif
  2552. static int i91u_bus_reset(struct scsi_cmnd * SCpnt)
  2553. {
  2554. HCS *pHCB;
  2555. pHCB = (HCS *) SCpnt->device->host->base;
  2556. spin_lock_irq(SCpnt->device->host->host_lock);
  2557. tul_reset_scsi(pHCB, 0);
  2558. spin_unlock_irq(SCpnt->device->host->host_lock);
  2559. return SUCCESS;
  2560. }
  2561. /*
  2562. * Return the "logical geometry"
  2563. */
  2564. static int i91u_biosparam(struct scsi_device *sdev, struct block_device *dev,
  2565. sector_t capacity, int *info_array)
  2566. {
  2567. HCS *pHcb; /* Point to Host adapter control block */
  2568. TCS *pTcb;
  2569. pHcb = (HCS *) sdev->host->base;
  2570. pTcb = &pHcb->HCS_Tcs[sdev->id];
  2571. if (pTcb->TCS_DrvHead) {
  2572. info_array[0] = pTcb->TCS_DrvHead;
  2573. info_array[1] = pTcb->TCS_DrvSector;
  2574. info_array[2] = (unsigned long)capacity / pTcb->TCS_DrvHead / pTcb->TCS_DrvSector;
  2575. } else {
  2576. if (pTcb->TCS_DrvFlags & TCF_DRV_255_63) {
  2577. info_array[0] = 255;
  2578. info_array[1] = 63;
  2579. info_array[2] = (unsigned long)capacity / 255 / 63;
  2580. } else {
  2581. info_array[0] = 64;
  2582. info_array[1] = 32;
  2583. info_array[2] = (unsigned long)capacity >> 11;
  2584. }
  2585. }
  2586. #if defined(DEBUG_BIOSPARAM)
  2587. if (i91u_debug & debug_biosparam) {
  2588. printk("bios geometry: head=%d, sec=%d, cyl=%d\n",
  2589. info_array[0], info_array[1], info_array[2]);
  2590. printk("WARNING: check, if the bios geometry is correct.\n");
  2591. }
  2592. #endif
  2593. return 0;
  2594. }
  2595. static void i91u_unmap_cmnd(struct pci_dev *pci_dev, struct scsi_cmnd *cmnd)
  2596. {
  2597. /* auto sense buffer */
  2598. if (cmnd->SCp.ptr) {
  2599. dma_unmap_single(&pci_dev->dev,
  2600. (dma_addr_t)((unsigned long)cmnd->SCp.ptr),
  2601. SENSE_SIZE, DMA_FROM_DEVICE);
  2602. cmnd->SCp.ptr = NULL;
  2603. }
  2604. /* request buffer */
  2605. if (cmnd->use_sg) {
  2606. dma_unmap_single(&pci_dev->dev, cmnd->SCp.dma_handle,
  2607. sizeof(struct SG_Struc) * TOTAL_SG_ENTRY,
  2608. DMA_BIDIRECTIONAL);
  2609. dma_unmap_sg(&pci_dev->dev, cmnd->request_buffer,
  2610. cmnd->use_sg,
  2611. cmnd->sc_data_direction);
  2612. } else if (cmnd->request_bufflen) {
  2613. dma_unmap_single(&pci_dev->dev, cmnd->SCp.dma_handle,
  2614. cmnd->request_bufflen,
  2615. cmnd->sc_data_direction);
  2616. }
  2617. }
  2618. /*****************************************************************************
  2619. Function name : i91uSCBPost
  2620. Description : This is callback routine be called when tulip finish one
  2621. SCSI command.
  2622. Input : pHCB - Pointer to host adapter control block.
  2623. pSCB - Pointer to SCSI control block.
  2624. Output : None.
  2625. Return : None.
  2626. *****************************************************************************/
  2627. static void i91uSCBPost(BYTE * pHcb, BYTE * pScb)
  2628. {
  2629. struct scsi_cmnd *pSRB; /* Pointer to SCSI request block */
  2630. HCS *pHCB;
  2631. SCB *pSCB;
  2632. pHCB = (HCS *) pHcb;
  2633. pSCB = (SCB *) pScb;
  2634. if ((pSRB = pSCB->SCB_Srb) == 0) {
  2635. printk("i91uSCBPost: SRB pointer is empty\n");
  2636. tul_release_scb(pHCB, pSCB); /* Release SCB for current channel */
  2637. return;
  2638. }
  2639. switch (pSCB->SCB_HaStat) {
  2640. case 0x0:
  2641. case 0xa: /* Linked command complete without error and linked normally */
  2642. case 0xb: /* Linked command complete without error interrupt generated */
  2643. pSCB->SCB_HaStat = 0;
  2644. break;
  2645. case 0x11: /* Selection time out-The initiator selection or target
  2646. reselection was not complete within the SCSI Time out period */
  2647. pSCB->SCB_HaStat = DID_TIME_OUT;
  2648. break;
  2649. case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus
  2650. phase sequence was requested by the target. The host adapter
  2651. will generate a SCSI Reset Condition, notifying the host with
  2652. a SCRD interrupt */
  2653. pSCB->SCB_HaStat = DID_RESET;
  2654. break;
  2655. case 0x1a: /* SCB Aborted. 07/21/98 */
  2656. pSCB->SCB_HaStat = DID_ABORT;
  2657. break;
  2658. case 0x12: /* Data overrun/underrun-The target attempted to transfer more data
  2659. than was allocated by the Data Length field or the sum of the
  2660. Scatter / Gather Data Length fields. */
  2661. case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */
  2662. case 0x16: /* Invalid SCB Operation Code. */
  2663. default:
  2664. printk("ini9100u: %x %x\n", pSCB->SCB_HaStat, pSCB->SCB_TaStat);
  2665. pSCB->SCB_HaStat = DID_ERROR; /* Couldn't find any better */
  2666. break;
  2667. }
  2668. pSRB->result = pSCB->SCB_TaStat | (pSCB->SCB_HaStat << 16);
  2669. if (pSRB == NULL) {
  2670. printk("pSRB is NULL\n");
  2671. }
  2672. i91u_unmap_cmnd(pHCB->pci_dev, pSRB);
  2673. pSRB->scsi_done(pSRB); /* Notify system DONE */
  2674. tul_release_scb(pHCB, pSCB); /* Release SCB for current channel */
  2675. }
  2676. /*
  2677. * Release ressources
  2678. */
  2679. static int i91u_release(struct Scsi_Host *hreg)
  2680. {
  2681. free_irq(hreg->irq, hreg);
  2682. release_region(hreg->io_port, 256);
  2683. return 0;
  2684. }
  2685. MODULE_LICENSE("Dual BSD/GPL");
  2686. static struct scsi_host_template driver_template = {
  2687. .proc_name = "INI9100U",
  2688. .name = i91u_REVID,
  2689. .detect = i91u_detect,
  2690. .release = i91u_release,
  2691. .queuecommand = i91u_queuecommand,
  2692. // .abort = i91u_abort,
  2693. // .reset = i91u_reset,
  2694. .eh_bus_reset_handler = i91u_bus_reset,
  2695. .bios_param = i91u_biosparam,
  2696. .can_queue = 1,
  2697. .this_id = 1,
  2698. .sg_tablesize = SG_ALL,
  2699. .cmd_per_lun = 1,
  2700. .use_clustering = ENABLE_CLUSTERING,
  2701. };
  2702. #include "scsi_module.c"