mptscsih.c 91 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267
  1. /*
  2. * linux/drivers/message/fusion/mptscsih.c
  3. * For use with LSI PCI chip/adapter(s)
  4. * running LSI Fusion MPT (Message Passing Technology) firmware.
  5. *
  6. * Copyright (c) 1999-2008 LSI Corporation
  7. * (mailto:DL-MPTFusionLinux@lsi.com)
  8. *
  9. */
  10. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  11. /*
  12. This program is free software; you can redistribute it and/or modify
  13. it under the terms of the GNU General Public License as published by
  14. the Free Software Foundation; version 2 of the License.
  15. This program is distributed in the hope that it will be useful,
  16. but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. GNU General Public License for more details.
  19. NO WARRANTY
  20. THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
  21. CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
  22. LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
  23. MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
  24. solely responsible for determining the appropriateness of using and
  25. distributing the Program and assumes all risks associated with its
  26. exercise of rights under this Agreement, including but not limited to
  27. the risks and costs of program errors, damage to or loss of data,
  28. programs or equipment, and unavailability or interruption of operations.
  29. DISCLAIMER OF LIABILITY
  30. NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
  31. DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  32. DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
  33. ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
  34. TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  35. USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
  36. HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
  37. You should have received a copy of the GNU General Public License
  38. along with this program; if not, write to the Free Software
  39. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  40. */
  41. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  42. #include <linux/module.h>
  43. #include <linux/kernel.h>
  44. #include <linux/slab.h>
  45. #include <linux/init.h>
  46. #include <linux/errno.h>
  47. #include <linux/kdev_t.h>
  48. #include <linux/blkdev.h>
  49. #include <linux/delay.h> /* for mdelay */
  50. #include <linux/interrupt.h> /* needed for in_interrupt() proto */
  51. #include <linux/reboot.h> /* notifier code */
  52. #include <linux/workqueue.h>
  53. #include <scsi/scsi.h>
  54. #include <scsi/scsi_cmnd.h>
  55. #include <scsi/scsi_device.h>
  56. #include <scsi/scsi_host.h>
  57. #include <scsi/scsi_tcq.h>
  58. #include <scsi/scsi_dbg.h>
  59. #include "mptbase.h"
  60. #include "mptscsih.h"
  61. #include "lsi/mpi_log_sas.h"
  62. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  63. #define my_NAME "Fusion MPT SCSI Host driver"
  64. #define my_VERSION MPT_LINUX_VERSION_COMMON
  65. #define MYNAM "mptscsih"
  66. MODULE_AUTHOR(MODULEAUTHOR);
  67. MODULE_DESCRIPTION(my_NAME);
  68. MODULE_LICENSE("GPL");
  69. MODULE_VERSION(my_VERSION);
  70. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  71. /*
  72. * Other private/forward protos...
  73. */
  74. struct scsi_cmnd *mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i);
  75. static struct scsi_cmnd * mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i);
  76. static void mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd);
  77. static int SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *scmd);
  78. int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
  79. static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
  80. int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
  81. static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
  82. SCSIIORequest_t *pReq, int req_idx);
  83. static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
  84. static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
  85. int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id,
  86. u64 lun, int ctx2abort, ulong timeout);
  87. int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
  88. int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
  89. void
  90. mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code);
  91. static int mptscsih_get_completion_code(MPT_ADAPTER *ioc,
  92. MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
  93. int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
  94. static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
  95. static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
  96. static int
  97. mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
  98. SCSITaskMgmtReply_t *pScsiTmReply);
  99. void mptscsih_remove(struct pci_dev *);
  100. void mptscsih_shutdown(struct pci_dev *);
  101. #ifdef CONFIG_PM
  102. int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
  103. int mptscsih_resume(struct pci_dev *pdev);
  104. #endif
  105. #define SNS_LEN(scp) SCSI_SENSE_BUFFERSIZE
  106. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  107. /*
  108. * mptscsih_getFreeChainBuffer - Function to get a free chain
  109. * from the MPT_SCSI_HOST FreeChainQ.
  110. * @ioc: Pointer to MPT_ADAPTER structure
  111. * @req_idx: Index of the SCSI IO request frame. (output)
  112. *
  113. * return SUCCESS or FAILED
  114. */
  115. static inline int
  116. mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
  117. {
  118. MPT_FRAME_HDR *chainBuf;
  119. unsigned long flags;
  120. int rc;
  121. int chain_idx;
  122. dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "getFreeChainBuffer called\n",
  123. ioc->name));
  124. spin_lock_irqsave(&ioc->FreeQlock, flags);
  125. if (!list_empty(&ioc->FreeChainQ)) {
  126. int offset;
  127. chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
  128. u.frame.linkage.list);
  129. list_del(&chainBuf->u.frame.linkage.list);
  130. offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
  131. chain_idx = offset / ioc->req_sz;
  132. rc = SUCCESS;
  133. dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  134. "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
  135. ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
  136. } else {
  137. rc = FAILED;
  138. chain_idx = MPT_HOST_NO_CHAIN;
  139. dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
  140. ioc->name));
  141. }
  142. spin_unlock_irqrestore(&ioc->FreeQlock, flags);
  143. *retIndex = chain_idx;
  144. return rc;
  145. } /* mptscsih_getFreeChainBuffer() */
  146. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  147. /*
  148. * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
  149. * SCSIIORequest_t Message Frame.
  150. * @ioc: Pointer to MPT_ADAPTER structure
  151. * @SCpnt: Pointer to scsi_cmnd structure
  152. * @pReq: Pointer to SCSIIORequest_t structure
  153. *
  154. * Returns ...
  155. */
  156. static int
  157. mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
  158. SCSIIORequest_t *pReq, int req_idx)
  159. {
  160. char *psge;
  161. char *chainSge;
  162. struct scatterlist *sg;
  163. int frm_sz;
  164. int sges_left, sg_done;
  165. int chain_idx = MPT_HOST_NO_CHAIN;
  166. int sgeOffset;
  167. int numSgeSlots, numSgeThisFrame;
  168. u32 sgflags, sgdir, thisxfer = 0;
  169. int chain_dma_off = 0;
  170. int newIndex;
  171. int ii;
  172. dma_addr_t v2;
  173. u32 RequestNB;
  174. sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
  175. if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
  176. sgdir = MPT_TRANSFER_HOST_TO_IOC;
  177. } else {
  178. sgdir = MPT_TRANSFER_IOC_TO_HOST;
  179. }
  180. psge = (char *) &pReq->SGL;
  181. frm_sz = ioc->req_sz;
  182. /* Map the data portion, if any.
  183. * sges_left = 0 if no data transfer.
  184. */
  185. sges_left = scsi_dma_map(SCpnt);
  186. if (sges_left < 0)
  187. return FAILED;
  188. /* Handle the SG case.
  189. */
  190. sg = scsi_sglist(SCpnt);
  191. sg_done = 0;
  192. sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
  193. chainSge = NULL;
  194. /* Prior to entering this loop - the following must be set
  195. * current MF: sgeOffset (bytes)
  196. * chainSge (Null if original MF is not a chain buffer)
  197. * sg_done (num SGE done for this MF)
  198. */
  199. nextSGEset:
  200. numSgeSlots = ((frm_sz - sgeOffset) / ioc->SGE_size);
  201. numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
  202. sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | sgdir;
  203. /* Get first (num - 1) SG elements
  204. * Skip any SG entries with a length of 0
  205. * NOTE: at finish, sg and psge pointed to NEXT data/location positions
  206. */
  207. for (ii=0; ii < (numSgeThisFrame-1); ii++) {
  208. thisxfer = sg_dma_len(sg);
  209. if (thisxfer == 0) {
  210. /* Get next SG element from the OS */
  211. sg = sg_next(sg);
  212. sg_done++;
  213. continue;
  214. }
  215. v2 = sg_dma_address(sg);
  216. ioc->add_sge(psge, sgflags | thisxfer, v2);
  217. /* Get next SG element from the OS */
  218. sg = sg_next(sg);
  219. psge += ioc->SGE_size;
  220. sgeOffset += ioc->SGE_size;
  221. sg_done++;
  222. }
  223. if (numSgeThisFrame == sges_left) {
  224. /* Add last element, end of buffer and end of list flags.
  225. */
  226. sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
  227. MPT_SGE_FLAGS_END_OF_BUFFER |
  228. MPT_SGE_FLAGS_END_OF_LIST;
  229. /* Add last SGE and set termination flags.
  230. * Note: Last SGE may have a length of 0 - which should be ok.
  231. */
  232. thisxfer = sg_dma_len(sg);
  233. v2 = sg_dma_address(sg);
  234. ioc->add_sge(psge, sgflags | thisxfer, v2);
  235. sgeOffset += ioc->SGE_size;
  236. sg_done++;
  237. if (chainSge) {
  238. /* The current buffer is a chain buffer,
  239. * but there is not another one.
  240. * Update the chain element
  241. * Offset and Length fields.
  242. */
  243. ioc->add_chain((char *)chainSge, 0, sgeOffset,
  244. ioc->ChainBufferDMA + chain_dma_off);
  245. } else {
  246. /* The current buffer is the original MF
  247. * and there is no Chain buffer.
  248. */
  249. pReq->ChainOffset = 0;
  250. RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
  251. dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  252. "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
  253. ioc->RequestNB[req_idx] = RequestNB;
  254. }
  255. } else {
  256. /* At least one chain buffer is needed.
  257. * Complete the first MF
  258. * - last SGE element, set the LastElement bit
  259. * - set ChainOffset (words) for orig MF
  260. * (OR finish previous MF chain buffer)
  261. * - update MFStructPtr ChainIndex
  262. * - Populate chain element
  263. * Also
  264. * Loop until done.
  265. */
  266. dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SG: Chain Required! sg done %d\n",
  267. ioc->name, sg_done));
  268. /* Set LAST_ELEMENT flag for last non-chain element
  269. * in the buffer. Since psge points at the NEXT
  270. * SGE element, go back one SGE element, update the flags
  271. * and reset the pointer. (Note: sgflags & thisxfer are already
  272. * set properly).
  273. */
  274. if (sg_done) {
  275. u32 *ptmp = (u32 *) (psge - ioc->SGE_size);
  276. sgflags = le32_to_cpu(*ptmp);
  277. sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
  278. *ptmp = cpu_to_le32(sgflags);
  279. }
  280. if (chainSge) {
  281. /* The current buffer is a chain buffer.
  282. * chainSge points to the previous Chain Element.
  283. * Update its chain element Offset and Length (must
  284. * include chain element size) fields.
  285. * Old chain element is now complete.
  286. */
  287. u8 nextChain = (u8) (sgeOffset >> 2);
  288. sgeOffset += ioc->SGE_size;
  289. ioc->add_chain((char *)chainSge, nextChain, sgeOffset,
  290. ioc->ChainBufferDMA + chain_dma_off);
  291. } else {
  292. /* The original MF buffer requires a chain buffer -
  293. * set the offset.
  294. * Last element in this MF is a chain element.
  295. */
  296. pReq->ChainOffset = (u8) (sgeOffset >> 2);
  297. RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
  298. dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
  299. ioc->RequestNB[req_idx] = RequestNB;
  300. }
  301. sges_left -= sg_done;
  302. /* NOTE: psge points to the beginning of the chain element
  303. * in current buffer. Get a chain buffer.
  304. */
  305. if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
  306. dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  307. "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
  308. ioc->name, pReq->CDB[0], SCpnt));
  309. return FAILED;
  310. }
  311. /* Update the tracking arrays.
  312. * If chainSge == NULL, update ReqToChain, else ChainToChain
  313. */
  314. if (chainSge) {
  315. ioc->ChainToChain[chain_idx] = newIndex;
  316. } else {
  317. ioc->ReqToChain[req_idx] = newIndex;
  318. }
  319. chain_idx = newIndex;
  320. chain_dma_off = ioc->req_sz * chain_idx;
  321. /* Populate the chainSGE for the current buffer.
  322. * - Set chain buffer pointer to psge and fill
  323. * out the Address and Flags fields.
  324. */
  325. chainSge = (char *) psge;
  326. dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT " Current buff @ %p (index 0x%x)",
  327. ioc->name, psge, req_idx));
  328. /* Start the SGE for the next buffer
  329. */
  330. psge = (char *) (ioc->ChainBuffer + chain_dma_off);
  331. sgeOffset = 0;
  332. sg_done = 0;
  333. dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT " Chain buff @ %p (index 0x%x)\n",
  334. ioc->name, psge, chain_idx));
  335. /* Start the SGE for the next buffer
  336. */
  337. goto nextSGEset;
  338. }
  339. return SUCCESS;
  340. } /* mptscsih_AddSGE() */
  341. static void
  342. mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
  343. U32 SlotStatus)
  344. {
  345. MPT_FRAME_HDR *mf;
  346. SEPRequest_t *SEPMsg;
  347. if (ioc->bus_type != SAS)
  348. return;
  349. /* Not supported for hidden raid components
  350. */
  351. if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
  352. return;
  353. if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
  354. dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
  355. ioc->name,__func__));
  356. return;
  357. }
  358. SEPMsg = (SEPRequest_t *)mf;
  359. SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
  360. SEPMsg->Bus = vtarget->channel;
  361. SEPMsg->TargetID = vtarget->id;
  362. SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
  363. SEPMsg->SlotStatus = SlotStatus;
  364. devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  365. "Sending SEP cmd=%x channel=%d id=%d\n",
  366. ioc->name, SlotStatus, SEPMsg->Bus, SEPMsg->TargetID));
  367. mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
  368. }
  369. #ifdef CONFIG_FUSION_LOGGING
  370. /**
  371. * mptscsih_info_scsiio - debug print info on reply frame
  372. * @ioc: Pointer to MPT_ADAPTER structure
  373. * @sc: original scsi cmnd pointer
  374. * @pScsiReply: Pointer to MPT reply frame
  375. *
  376. * MPT_DEBUG_REPLY needs to be enabled to obtain this info
  377. *
  378. * Refer to lsi/mpi.h.
  379. **/
  380. static void
  381. mptscsih_info_scsiio(MPT_ADAPTER *ioc, struct scsi_cmnd *sc, SCSIIOReply_t * pScsiReply)
  382. {
  383. char *desc = NULL;
  384. char *desc1 = NULL;
  385. u16 ioc_status;
  386. u8 skey, asc, ascq;
  387. ioc_status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
  388. switch (ioc_status) {
  389. case MPI_IOCSTATUS_SUCCESS:
  390. desc = "success";
  391. break;
  392. case MPI_IOCSTATUS_SCSI_INVALID_BUS:
  393. desc = "invalid bus";
  394. break;
  395. case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:
  396. desc = "invalid target_id";
  397. break;
  398. case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
  399. desc = "device not there";
  400. break;
  401. case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:
  402. desc = "data overrun";
  403. break;
  404. case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:
  405. desc = "data underrun";
  406. break;
  407. case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:
  408. desc = "I/O data error";
  409. break;
  410. case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:
  411. desc = "protocol error";
  412. break;
  413. case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:
  414. desc = "task terminated";
  415. break;
  416. case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
  417. desc = "residual mismatch";
  418. break;
  419. case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
  420. desc = "task management failed";
  421. break;
  422. case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:
  423. desc = "IOC terminated";
  424. break;
  425. case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:
  426. desc = "ext terminated";
  427. break;
  428. default:
  429. desc = "";
  430. break;
  431. }
  432. switch (pScsiReply->SCSIStatus)
  433. {
  434. case MPI_SCSI_STATUS_SUCCESS:
  435. desc1 = "success";
  436. break;
  437. case MPI_SCSI_STATUS_CHECK_CONDITION:
  438. desc1 = "check condition";
  439. break;
  440. case MPI_SCSI_STATUS_CONDITION_MET:
  441. desc1 = "condition met";
  442. break;
  443. case MPI_SCSI_STATUS_BUSY:
  444. desc1 = "busy";
  445. break;
  446. case MPI_SCSI_STATUS_INTERMEDIATE:
  447. desc1 = "intermediate";
  448. break;
  449. case MPI_SCSI_STATUS_INTERMEDIATE_CONDMET:
  450. desc1 = "intermediate condmet";
  451. break;
  452. case MPI_SCSI_STATUS_RESERVATION_CONFLICT:
  453. desc1 = "reservation conflict";
  454. break;
  455. case MPI_SCSI_STATUS_COMMAND_TERMINATED:
  456. desc1 = "command terminated";
  457. break;
  458. case MPI_SCSI_STATUS_TASK_SET_FULL:
  459. desc1 = "task set full";
  460. break;
  461. case MPI_SCSI_STATUS_ACA_ACTIVE:
  462. desc1 = "aca active";
  463. break;
  464. case MPI_SCSI_STATUS_FCPEXT_DEVICE_LOGGED_OUT:
  465. desc1 = "fcpext device logged out";
  466. break;
  467. case MPI_SCSI_STATUS_FCPEXT_NO_LINK:
  468. desc1 = "fcpext no link";
  469. break;
  470. case MPI_SCSI_STATUS_FCPEXT_UNASSIGNED:
  471. desc1 = "fcpext unassigned";
  472. break;
  473. default:
  474. desc1 = "";
  475. break;
  476. }
  477. scsi_print_command(sc);
  478. printk(MYIOC_s_DEBUG_FMT "\tfw_channel = %d, fw_id = %d, lun = %llu\n",
  479. ioc->name, pScsiReply->Bus, pScsiReply->TargetID, sc->device->lun);
  480. printk(MYIOC_s_DEBUG_FMT "\trequest_len = %d, underflow = %d, "
  481. "resid = %d\n", ioc->name, scsi_bufflen(sc), sc->underflow,
  482. scsi_get_resid(sc));
  483. printk(MYIOC_s_DEBUG_FMT "\ttag = %d, transfer_count = %d, "
  484. "sc->result = %08X\n", ioc->name, le16_to_cpu(pScsiReply->TaskTag),
  485. le32_to_cpu(pScsiReply->TransferCount), sc->result);
  486. printk(MYIOC_s_DEBUG_FMT "\tiocstatus = %s (0x%04x), "
  487. "scsi_status = %s (0x%02x), scsi_state = (0x%02x)\n",
  488. ioc->name, desc, ioc_status, desc1, pScsiReply->SCSIStatus,
  489. pScsiReply->SCSIState);
  490. if (pScsiReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
  491. skey = sc->sense_buffer[2] & 0x0F;
  492. asc = sc->sense_buffer[12];
  493. ascq = sc->sense_buffer[13];
  494. printk(MYIOC_s_DEBUG_FMT "\t[sense_key,asc,ascq]: "
  495. "[0x%02x,0x%02x,0x%02x]\n", ioc->name, skey, asc, ascq);
  496. }
  497. /*
  498. * Look for + dump FCP ResponseInfo[]!
  499. */
  500. if (pScsiReply->SCSIState & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
  501. pScsiReply->ResponseInfo)
  502. printk(MYIOC_s_DEBUG_FMT "response_info = %08xh\n",
  503. ioc->name, le32_to_cpu(pScsiReply->ResponseInfo));
  504. }
  505. #endif
  506. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  507. /*
  508. * mptscsih_io_done - Main SCSI IO callback routine registered to
  509. * Fusion MPT (base) driver
  510. * @ioc: Pointer to MPT_ADAPTER structure
  511. * @mf: Pointer to original MPT request frame
  512. * @r: Pointer to MPT reply frame (NULL if TurboReply)
  513. *
  514. * This routine is called from mpt.c::mpt_interrupt() at the completion
  515. * of any SCSI IO request.
  516. * This routine is registered with the Fusion MPT (base) driver at driver
  517. * load/init time via the mpt_register() API call.
  518. *
  519. * Returns 1 indicating alloc'd request frame ptr should be freed.
  520. */
  521. int
  522. mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
  523. {
  524. struct scsi_cmnd *sc;
  525. MPT_SCSI_HOST *hd;
  526. SCSIIORequest_t *pScsiReq;
  527. SCSIIOReply_t *pScsiReply;
  528. u16 req_idx, req_idx_MR;
  529. VirtDevice *vdevice;
  530. VirtTarget *vtarget;
  531. hd = shost_priv(ioc->sh);
  532. req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
  533. req_idx_MR = (mr != NULL) ?
  534. le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
  535. /* Special case, where already freed message frame is received from
  536. * Firmware. It happens with Resetting IOC.
  537. * Return immediately. Do not care
  538. */
  539. if ((req_idx != req_idx_MR) ||
  540. (le32_to_cpu(mf->u.frame.linkage.arg1) == 0xdeadbeaf))
  541. return 0;
  542. sc = mptscsih_getclear_scsi_lookup(ioc, req_idx);
  543. if (sc == NULL) {
  544. MPIHeader_t *hdr = (MPIHeader_t *)mf;
  545. /* Remark: writeSDP1 will use the ScsiDoneCtx
  546. * If a SCSI I/O cmd, device disabled by OS and
  547. * completion done. Cannot touch sc struct. Just free mem.
  548. */
  549. if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
  550. printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
  551. ioc->name);
  552. mptscsih_freeChainBuffers(ioc, req_idx);
  553. return 1;
  554. }
  555. if ((unsigned char *)mf != sc->host_scribble) {
  556. mptscsih_freeChainBuffers(ioc, req_idx);
  557. return 1;
  558. }
  559. if (ioc->bus_type == SAS) {
  560. VirtDevice *vdevice = sc->device->hostdata;
  561. if (!vdevice || !vdevice->vtarget ||
  562. vdevice->vtarget->deleted) {
  563. sc->result = DID_NO_CONNECT << 16;
  564. goto out;
  565. }
  566. }
  567. sc->host_scribble = NULL;
  568. sc->result = DID_OK << 16; /* Set default reply as OK */
  569. pScsiReq = (SCSIIORequest_t *) mf;
  570. pScsiReply = (SCSIIOReply_t *) mr;
  571. if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
  572. dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  573. "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
  574. ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
  575. }else{
  576. dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  577. "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
  578. ioc->name, mf, mr, sc, req_idx));
  579. }
  580. if (pScsiReply == NULL) {
  581. /* special context reply handling */
  582. ;
  583. } else {
  584. u32 xfer_cnt;
  585. u16 status;
  586. u8 scsi_state, scsi_status;
  587. u32 log_info;
  588. status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
  589. scsi_state = pScsiReply->SCSIState;
  590. scsi_status = pScsiReply->SCSIStatus;
  591. xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
  592. scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
  593. log_info = le32_to_cpu(pScsiReply->IOCLogInfo);
  594. /*
  595. * if we get a data underrun indication, yet no data was
  596. * transferred and the SCSI status indicates that the
  597. * command was never started, change the data underrun
  598. * to success
  599. */
  600. if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
  601. (scsi_status == MPI_SCSI_STATUS_BUSY ||
  602. scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
  603. scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
  604. status = MPI_IOCSTATUS_SUCCESS;
  605. }
  606. if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
  607. mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
  608. /*
  609. * Look for + dump FCP ResponseInfo[]!
  610. */
  611. if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
  612. pScsiReply->ResponseInfo) {
  613. printk(MYIOC_s_NOTE_FMT "[%d:%d:%d:%llu] "
  614. "FCP_ResponseInfo=%08xh\n", ioc->name,
  615. sc->device->host->host_no, sc->device->channel,
  616. sc->device->id, sc->device->lun,
  617. le32_to_cpu(pScsiReply->ResponseInfo));
  618. }
  619. switch(status) {
  620. case MPI_IOCSTATUS_BUSY: /* 0x0002 */
  621. case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
  622. /* CHECKME!
  623. * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
  624. * But not: DID_BUS_BUSY lest one risk
  625. * killing interrupt handler:-(
  626. */
  627. sc->result = SAM_STAT_BUSY;
  628. break;
  629. case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
  630. case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
  631. sc->result = DID_BAD_TARGET << 16;
  632. break;
  633. case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
  634. /* Spoof to SCSI Selection Timeout! */
  635. if (ioc->bus_type != FC)
  636. sc->result = DID_NO_CONNECT << 16;
  637. /* else fibre, just stall until rescan event */
  638. else
  639. sc->result = DID_REQUEUE << 16;
  640. if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
  641. hd->sel_timeout[pScsiReq->TargetID]++;
  642. vdevice = sc->device->hostdata;
  643. if (!vdevice)
  644. break;
  645. vtarget = vdevice->vtarget;
  646. if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
  647. mptscsih_issue_sep_command(ioc, vtarget,
  648. MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
  649. vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
  650. }
  651. break;
  652. case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
  653. if ( ioc->bus_type == SAS ) {
  654. u16 ioc_status =
  655. le16_to_cpu(pScsiReply->IOCStatus);
  656. if ((ioc_status &
  657. MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE)
  658. &&
  659. ((log_info & SAS_LOGINFO_MASK) ==
  660. SAS_LOGINFO_NEXUS_LOSS)) {
  661. VirtDevice *vdevice =
  662. sc->device->hostdata;
  663. /* flag the device as being in
  664. * device removal delay so we can
  665. * notify the midlayer to hold off
  666. * on timeout eh */
  667. if (vdevice && vdevice->
  668. vtarget &&
  669. vdevice->vtarget->
  670. raidVolume)
  671. printk(KERN_INFO
  672. "Skipping Raid Volume"
  673. "for inDMD\n");
  674. else if (vdevice &&
  675. vdevice->vtarget)
  676. vdevice->vtarget->
  677. inDMD = 1;
  678. sc->result =
  679. (DID_TRANSPORT_DISRUPTED
  680. << 16);
  681. break;
  682. }
  683. } else if (ioc->bus_type == FC) {
  684. /*
  685. * The FC IOC may kill a request for variety of
  686. * reasons, some of which may be recovered by a
  687. * retry, some which are unlikely to be
  688. * recovered. Return DID_ERROR instead of
  689. * DID_RESET to permit retry of the command,
  690. * just not an infinite number of them
  691. */
  692. sc->result = DID_ERROR << 16;
  693. break;
  694. }
  695. /*
  696. * Allow non-SAS & non-NEXUS_LOSS to drop into below code
  697. */
  698. case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
  699. /* Linux handles an unsolicited DID_RESET better
  700. * than an unsolicited DID_ABORT.
  701. */
  702. sc->result = DID_RESET << 16;
  703. break;
  704. case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
  705. if (ioc->bus_type == FC)
  706. sc->result = DID_ERROR << 16;
  707. else
  708. sc->result = DID_RESET << 16;
  709. break;
  710. case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
  711. scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
  712. if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
  713. sc->result=DID_SOFT_ERROR << 16;
  714. else /* Sufficient data transfer occurred */
  715. sc->result = (DID_OK << 16) | scsi_status;
  716. dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  717. "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n",
  718. ioc->name, sc->result, sc->device->channel, sc->device->id));
  719. break;
  720. case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
  721. /*
  722. * Do upfront check for valid SenseData and give it
  723. * precedence!
  724. */
  725. sc->result = (DID_OK << 16) | scsi_status;
  726. if (!(scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
  727. /*
  728. * For an Errata on LSI53C1030
  729. * When the length of request data
  730. * and transfer data are different
  731. * with result of command (READ or VERIFY),
  732. * DID_SOFT_ERROR is set.
  733. */
  734. if (ioc->bus_type == SPI) {
  735. if ((pScsiReq->CDB[0] == READ_6 && ((pScsiReq->CDB[1] & 0x02) == 0)) ||
  736. pScsiReq->CDB[0] == READ_10 ||
  737. pScsiReq->CDB[0] == READ_12 ||
  738. (pScsiReq->CDB[0] == READ_16 &&
  739. ((pScsiReq->CDB[1] & 0x02) == 0)) ||
  740. pScsiReq->CDB[0] == VERIFY ||
  741. pScsiReq->CDB[0] == VERIFY_16) {
  742. if (scsi_bufflen(sc) !=
  743. xfer_cnt) {
  744. sc->result =
  745. DID_SOFT_ERROR << 16;
  746. printk(KERN_WARNING "Errata"
  747. "on LSI53C1030 occurred."
  748. "sc->req_bufflen=0x%02x,"
  749. "xfer_cnt=0x%02x\n",
  750. scsi_bufflen(sc),
  751. xfer_cnt);
  752. }
  753. }
  754. }
  755. if (xfer_cnt < sc->underflow) {
  756. if (scsi_status == SAM_STAT_BUSY)
  757. sc->result = SAM_STAT_BUSY;
  758. else
  759. sc->result = DID_SOFT_ERROR << 16;
  760. }
  761. if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
  762. /* What to do?
  763. */
  764. sc->result = DID_SOFT_ERROR << 16;
  765. }
  766. else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
  767. /* Not real sure here either... */
  768. sc->result = DID_RESET << 16;
  769. }
  770. }
  771. dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  772. " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
  773. ioc->name, sc->underflow));
  774. dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  775. " ActBytesXferd=%02xh\n", ioc->name, xfer_cnt));
  776. /* Report Queue Full
  777. */
  778. if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
  779. mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
  780. break;
  781. case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
  782. scsi_set_resid(sc, 0);
  783. case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
  784. case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
  785. sc->result = (DID_OK << 16) | scsi_status;
  786. if (scsi_state == 0) {
  787. ;
  788. } else if (scsi_state &
  789. MPI_SCSI_STATE_AUTOSENSE_VALID) {
  790. /*
  791. * For potential trouble on LSI53C1030.
  792. * (date:2007.xx.)
  793. * It is checked whether the length of
  794. * request data is equal to
  795. * the length of transfer and residual.
  796. * MEDIUM_ERROR is set by incorrect data.
  797. */
  798. if ((ioc->bus_type == SPI) &&
  799. (sc->sense_buffer[2] & 0x20)) {
  800. u32 difftransfer;
  801. difftransfer =
  802. sc->sense_buffer[3] << 24 |
  803. sc->sense_buffer[4] << 16 |
  804. sc->sense_buffer[5] << 8 |
  805. sc->sense_buffer[6];
  806. if (((sc->sense_buffer[3] & 0x80) ==
  807. 0x80) && (scsi_bufflen(sc)
  808. != xfer_cnt)) {
  809. sc->sense_buffer[2] =
  810. MEDIUM_ERROR;
  811. sc->sense_buffer[12] = 0xff;
  812. sc->sense_buffer[13] = 0xff;
  813. printk(KERN_WARNING"Errata"
  814. "on LSI53C1030 occurred."
  815. "sc->req_bufflen=0x%02x,"
  816. "xfer_cnt=0x%02x\n" ,
  817. scsi_bufflen(sc),
  818. xfer_cnt);
  819. }
  820. if (((sc->sense_buffer[3] & 0x80)
  821. != 0x80) &&
  822. (scsi_bufflen(sc) !=
  823. xfer_cnt + difftransfer)) {
  824. sc->sense_buffer[2] =
  825. MEDIUM_ERROR;
  826. sc->sense_buffer[12] = 0xff;
  827. sc->sense_buffer[13] = 0xff;
  828. printk(KERN_WARNING
  829. "Errata on LSI53C1030 occurred"
  830. "sc->req_bufflen=0x%02x,"
  831. " xfer_cnt=0x%02x,"
  832. "difftransfer=0x%02x\n",
  833. scsi_bufflen(sc),
  834. xfer_cnt,
  835. difftransfer);
  836. }
  837. }
  838. /*
  839. * If running against circa 200003dd 909 MPT f/w,
  840. * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
  841. * (QUEUE_FULL) returned from device! --> get 0x0000?128
  842. * and with SenseBytes set to 0.
  843. */
  844. if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
  845. mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
  846. }
  847. else if (scsi_state &
  848. (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
  849. ) {
  850. /*
  851. * What to do?
  852. */
  853. sc->result = DID_SOFT_ERROR << 16;
  854. }
  855. else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
  856. /* Not real sure here either... */
  857. sc->result = DID_RESET << 16;
  858. }
  859. else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
  860. /* Device Inq. data indicates that it supports
  861. * QTags, but rejects QTag messages.
  862. * This command completed OK.
  863. *
  864. * Not real sure here either so do nothing... */
  865. }
  866. if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
  867. mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
  868. /* Add handling of:
  869. * Reservation Conflict, Busy,
  870. * Command Terminated, CHECK
  871. */
  872. break;
  873. case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
  874. sc->result = DID_SOFT_ERROR << 16;
  875. break;
  876. case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
  877. case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
  878. case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
  879. case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
  880. case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
  881. case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
  882. case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
  883. case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
  884. default:
  885. /*
  886. * What to do?
  887. */
  888. sc->result = DID_SOFT_ERROR << 16;
  889. break;
  890. } /* switch(status) */
  891. #ifdef CONFIG_FUSION_LOGGING
  892. if (sc->result && (ioc->debug_level & MPT_DEBUG_REPLY))
  893. mptscsih_info_scsiio(ioc, sc, pScsiReply);
  894. #endif
  895. } /* end of address reply case */
  896. out:
  897. /* Unmap the DMA buffers, if any. */
  898. scsi_dma_unmap(sc);
  899. sc->scsi_done(sc); /* Issue the command callback */
  900. /* Free Chain buffers */
  901. mptscsih_freeChainBuffers(ioc, req_idx);
  902. return 1;
  903. }
  904. /*
  905. * mptscsih_flush_running_cmds - For each command found, search
  906. * Scsi_Host instance taskQ and reply to OS.
  907. * Called only if recovering from a FW reload.
  908. * @hd: Pointer to a SCSI HOST structure
  909. *
  910. * Returns: None.
  911. *
  912. * Must be called while new I/Os are being queued.
  913. */
  914. void
  915. mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
  916. {
  917. MPT_ADAPTER *ioc = hd->ioc;
  918. struct scsi_cmnd *sc;
  919. SCSIIORequest_t *mf = NULL;
  920. int ii;
  921. int channel, id;
  922. for (ii= 0; ii < ioc->req_depth; ii++) {
  923. sc = mptscsih_getclear_scsi_lookup(ioc, ii);
  924. if (!sc)
  925. continue;
  926. mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii);
  927. if (!mf)
  928. continue;
  929. channel = mf->Bus;
  930. id = mf->TargetID;
  931. mptscsih_freeChainBuffers(ioc, ii);
  932. mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf);
  933. if ((unsigned char *)mf != sc->host_scribble)
  934. continue;
  935. scsi_dma_unmap(sc);
  936. sc->result = DID_RESET << 16;
  937. sc->host_scribble = NULL;
  938. dtmprintk(ioc, sdev_printk(KERN_INFO, sc->device, MYIOC_s_FMT
  939. "completing cmds: fw_channel %d, fw_id %d, sc=%p, mf = %p, "
  940. "idx=%x\n", ioc->name, channel, id, sc, mf, ii));
  941. sc->scsi_done(sc);
  942. }
  943. }
  944. EXPORT_SYMBOL(mptscsih_flush_running_cmds);
  945. /*
  946. * mptscsih_search_running_cmds - Delete any commands associated
  947. * with the specified target and lun. Function called only
  948. * when a lun is disable by mid-layer.
  949. * Do NOT access the referenced scsi_cmnd structure or
  950. * members. Will cause either a paging or NULL ptr error.
  951. * (BUT, BUT, BUT, the code does reference it! - mdr)
  952. * @hd: Pointer to a SCSI HOST structure
  953. * @vdevice: per device private data
  954. *
  955. * Returns: None.
  956. *
  957. * Called from slave_destroy.
  958. */
  959. static void
  960. mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
  961. {
  962. SCSIIORequest_t *mf = NULL;
  963. int ii;
  964. struct scsi_cmnd *sc;
  965. struct scsi_lun lun;
  966. MPT_ADAPTER *ioc = hd->ioc;
  967. unsigned long flags;
  968. spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
  969. for (ii = 0; ii < ioc->req_depth; ii++) {
  970. if ((sc = ioc->ScsiLookup[ii]) != NULL) {
  971. mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii);
  972. if (mf == NULL)
  973. continue;
  974. /* If the device is a hidden raid component, then its
  975. * expected that the mf->function will be RAID_SCSI_IO
  976. */
  977. if (vdevice->vtarget->tflags &
  978. MPT_TARGET_FLAGS_RAID_COMPONENT && mf->Function !=
  979. MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
  980. continue;
  981. int_to_scsilun(vdevice->lun, &lun);
  982. if ((mf->Bus != vdevice->vtarget->channel) ||
  983. (mf->TargetID != vdevice->vtarget->id) ||
  984. memcmp(lun.scsi_lun, mf->LUN, 8))
  985. continue;
  986. if ((unsigned char *)mf != sc->host_scribble)
  987. continue;
  988. ioc->ScsiLookup[ii] = NULL;
  989. spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
  990. mptscsih_freeChainBuffers(ioc, ii);
  991. mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf);
  992. scsi_dma_unmap(sc);
  993. sc->host_scribble = NULL;
  994. sc->result = DID_NO_CONNECT << 16;
  995. dtmprintk(ioc, sdev_printk(KERN_INFO, sc->device,
  996. MYIOC_s_FMT "completing cmds: fw_channel %d, "
  997. "fw_id %d, sc=%p, mf = %p, idx=%x\n", ioc->name,
  998. vdevice->vtarget->channel, vdevice->vtarget->id,
  999. sc, mf, ii));
  1000. sc->scsi_done(sc);
  1001. spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
  1002. }
  1003. }
  1004. spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
  1005. return;
  1006. }
  1007. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1008. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1009. /*
  1010. * mptscsih_report_queue_full - Report QUEUE_FULL status returned
  1011. * from a SCSI target device.
  1012. * @sc: Pointer to scsi_cmnd structure
  1013. * @pScsiReply: Pointer to SCSIIOReply_t
  1014. * @pScsiReq: Pointer to original SCSI request
  1015. *
  1016. * This routine periodically reports QUEUE_FULL status returned from a
  1017. * SCSI target device. It reports this to the console via kernel
  1018. * printk() API call, not more than once every 10 seconds.
  1019. */
  1020. static void
  1021. mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
  1022. {
  1023. long time = jiffies;
  1024. MPT_SCSI_HOST *hd;
  1025. MPT_ADAPTER *ioc;
  1026. if (sc->device == NULL)
  1027. return;
  1028. if (sc->device->host == NULL)
  1029. return;
  1030. if ((hd = shost_priv(sc->device->host)) == NULL)
  1031. return;
  1032. ioc = hd->ioc;
  1033. if (time - hd->last_queue_full > 10 * HZ) {
  1034. dprintk(ioc, printk(MYIOC_s_WARN_FMT "Device (%d:%d:%llu) reported QUEUE_FULL!\n",
  1035. ioc->name, 0, sc->device->id, sc->device->lun));
  1036. hd->last_queue_full = time;
  1037. }
  1038. }
  1039. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1040. /*
  1041. * mptscsih_remove - Removed scsi devices
  1042. * @pdev: Pointer to pci_dev structure
  1043. *
  1044. *
  1045. */
  1046. void
  1047. mptscsih_remove(struct pci_dev *pdev)
  1048. {
  1049. MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
  1050. struct Scsi_Host *host = ioc->sh;
  1051. MPT_SCSI_HOST *hd;
  1052. int sz1;
  1053. scsi_remove_host(host);
  1054. if((hd = shost_priv(host)) == NULL)
  1055. return;
  1056. mptscsih_shutdown(pdev);
  1057. sz1=0;
  1058. if (ioc->ScsiLookup != NULL) {
  1059. sz1 = ioc->req_depth * sizeof(void *);
  1060. kfree(ioc->ScsiLookup);
  1061. ioc->ScsiLookup = NULL;
  1062. }
  1063. dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  1064. "Free'd ScsiLookup (%d) memory\n",
  1065. ioc->name, sz1));
  1066. kfree(hd->info_kbuf);
  1067. /* NULL the Scsi_Host pointer
  1068. */
  1069. ioc->sh = NULL;
  1070. scsi_host_put(host);
  1071. mpt_detach(pdev);
  1072. }
  1073. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1074. /*
  1075. * mptscsih_shutdown - reboot notifier
  1076. *
  1077. */
  1078. void
  1079. mptscsih_shutdown(struct pci_dev *pdev)
  1080. {
  1081. }
  1082. #ifdef CONFIG_PM
  1083. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1084. /*
  1085. * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
  1086. *
  1087. *
  1088. */
  1089. int
  1090. mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
  1091. {
  1092. MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
  1093. scsi_block_requests(ioc->sh);
  1094. flush_scheduled_work();
  1095. mptscsih_shutdown(pdev);
  1096. return mpt_suspend(pdev,state);
  1097. }
  1098. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1099. /*
  1100. * mptscsih_resume - Fusion MPT scsi driver resume routine.
  1101. *
  1102. *
  1103. */
  1104. int
  1105. mptscsih_resume(struct pci_dev *pdev)
  1106. {
  1107. MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
  1108. int rc;
  1109. rc = mpt_resume(pdev);
  1110. scsi_unblock_requests(ioc->sh);
  1111. return rc;
  1112. }
  1113. #endif
  1114. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1115. /**
  1116. * mptscsih_info - Return information about MPT adapter
  1117. * @SChost: Pointer to Scsi_Host structure
  1118. *
  1119. * (linux scsi_host_template.info routine)
  1120. *
  1121. * Returns pointer to buffer where information was written.
  1122. */
  1123. const char *
  1124. mptscsih_info(struct Scsi_Host *SChost)
  1125. {
  1126. MPT_SCSI_HOST *h;
  1127. int size = 0;
  1128. h = shost_priv(SChost);
  1129. if (h->info_kbuf == NULL)
  1130. if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
  1131. return h->info_kbuf;
  1132. h->info_kbuf[0] = '\0';
  1133. mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
  1134. h->info_kbuf[size-1] = '\0';
  1135. return h->info_kbuf;
  1136. }
  1137. int mptscsih_show_info(struct seq_file *m, struct Scsi_Host *host)
  1138. {
  1139. MPT_SCSI_HOST *hd = shost_priv(host);
  1140. MPT_ADAPTER *ioc = hd->ioc;
  1141. seq_printf(m, "%s: %s, ", ioc->name, ioc->prod_name);
  1142. seq_printf(m, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
  1143. seq_printf(m, "Ports=%d, ", ioc->facts.NumberOfPorts);
  1144. seq_printf(m, "MaxQ=%d\n", ioc->req_depth);
  1145. return 0;
  1146. }
  1147. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1148. #define ADD_INDEX_LOG(req_ent) do { } while(0)
  1149. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1150. /**
  1151. * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
  1152. * @SCpnt: Pointer to scsi_cmnd structure
  1153. *
  1154. * (linux scsi_host_template.queuecommand routine)
  1155. * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
  1156. * from a linux scsi_cmnd request and send it to the IOC.
  1157. *
  1158. * Returns 0. (rtn value discarded by linux scsi mid-layer)
  1159. */
  1160. int
  1161. mptscsih_qcmd(struct scsi_cmnd *SCpnt)
  1162. {
  1163. MPT_SCSI_HOST *hd;
  1164. MPT_FRAME_HDR *mf;
  1165. SCSIIORequest_t *pScsiReq;
  1166. VirtDevice *vdevice = SCpnt->device->hostdata;
  1167. u32 datalen;
  1168. u32 scsictl;
  1169. u32 scsidir;
  1170. u32 cmd_len;
  1171. int my_idx;
  1172. int ii;
  1173. MPT_ADAPTER *ioc;
  1174. hd = shost_priv(SCpnt->device->host);
  1175. ioc = hd->ioc;
  1176. dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p\n",
  1177. ioc->name, SCpnt));
  1178. if (ioc->taskmgmt_quiesce_io)
  1179. return SCSI_MLQUEUE_HOST_BUSY;
  1180. /*
  1181. * Put together a MPT SCSI request...
  1182. */
  1183. if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
  1184. dprintk(ioc, printk(MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
  1185. ioc->name));
  1186. return SCSI_MLQUEUE_HOST_BUSY;
  1187. }
  1188. pScsiReq = (SCSIIORequest_t *) mf;
  1189. my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
  1190. ADD_INDEX_LOG(my_idx);
  1191. /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
  1192. * Seems we may receive a buffer (datalen>0) even when there
  1193. * will be no data transfer! GRRRRR...
  1194. */
  1195. if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
  1196. datalen = scsi_bufflen(SCpnt);
  1197. scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
  1198. } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
  1199. datalen = scsi_bufflen(SCpnt);
  1200. scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
  1201. } else {
  1202. datalen = 0;
  1203. scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
  1204. }
  1205. /* Default to untagged. Once a target structure has been allocated,
  1206. * use the Inquiry data to determine if device supports tagged.
  1207. */
  1208. if ((vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
  1209. && (SCpnt->device->tagged_supported)) {
  1210. scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
  1211. if (SCpnt->request && SCpnt->request->ioprio) {
  1212. if (((SCpnt->request->ioprio & 0x7) == 1) ||
  1213. !(SCpnt->request->ioprio & 0x7))
  1214. scsictl |= MPI_SCSIIO_CONTROL_HEADOFQ;
  1215. }
  1216. } else
  1217. scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
  1218. /* Use the above information to set up the message frame
  1219. */
  1220. pScsiReq->TargetID = (u8) vdevice->vtarget->id;
  1221. pScsiReq->Bus = vdevice->vtarget->channel;
  1222. pScsiReq->ChainOffset = 0;
  1223. if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
  1224. pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
  1225. else
  1226. pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
  1227. pScsiReq->CDBLength = SCpnt->cmd_len;
  1228. pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
  1229. pScsiReq->Reserved = 0;
  1230. pScsiReq->MsgFlags = mpt_msg_flags(ioc);
  1231. int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
  1232. pScsiReq->Control = cpu_to_le32(scsictl);
  1233. /*
  1234. * Write SCSI CDB into the message
  1235. */
  1236. cmd_len = SCpnt->cmd_len;
  1237. for (ii=0; ii < cmd_len; ii++)
  1238. pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
  1239. for (ii=cmd_len; ii < 16; ii++)
  1240. pScsiReq->CDB[ii] = 0;
  1241. /* DataLength */
  1242. pScsiReq->DataLength = cpu_to_le32(datalen);
  1243. /* SenseBuffer low address */
  1244. pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
  1245. + (my_idx * MPT_SENSE_BUFFER_ALLOC));
  1246. /* Now add the SG list
  1247. * Always have a SGE even if null length.
  1248. */
  1249. if (datalen == 0) {
  1250. /* Add a NULL SGE */
  1251. ioc->add_sge((char *)&pScsiReq->SGL,
  1252. MPT_SGE_FLAGS_SSIMPLE_READ | 0,
  1253. (dma_addr_t) -1);
  1254. } else {
  1255. /* Add a 32 or 64 bit SGE */
  1256. if (mptscsih_AddSGE(ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
  1257. goto fail;
  1258. }
  1259. SCpnt->host_scribble = (unsigned char *)mf;
  1260. mptscsih_set_scsi_lookup(ioc, my_idx, SCpnt);
  1261. mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
  1262. dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
  1263. ioc->name, SCpnt, mf, my_idx));
  1264. DBG_DUMP_REQUEST_FRAME(ioc, (u32 *)mf);
  1265. return 0;
  1266. fail:
  1267. mptscsih_freeChainBuffers(ioc, my_idx);
  1268. mpt_free_msg_frame(ioc, mf);
  1269. return SCSI_MLQUEUE_HOST_BUSY;
  1270. }
  1271. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1272. /*
  1273. * mptscsih_freeChainBuffers - Function to free chain buffers associated
  1274. * with a SCSI IO request
  1275. * @hd: Pointer to the MPT_SCSI_HOST instance
  1276. * @req_idx: Index of the SCSI IO request frame.
  1277. *
  1278. * Called if SG chain buffer allocation fails and mptscsih callbacks.
  1279. * No return.
  1280. */
  1281. static void
  1282. mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
  1283. {
  1284. MPT_FRAME_HDR *chain;
  1285. unsigned long flags;
  1286. int chain_idx;
  1287. int next;
  1288. /* Get the first chain index and reset
  1289. * tracker state.
  1290. */
  1291. chain_idx = ioc->ReqToChain[req_idx];
  1292. ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
  1293. while (chain_idx != MPT_HOST_NO_CHAIN) {
  1294. /* Save the next chain buffer index */
  1295. next = ioc->ChainToChain[chain_idx];
  1296. /* Free this chain buffer and reset
  1297. * tracker
  1298. */
  1299. ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
  1300. chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
  1301. + (chain_idx * ioc->req_sz));
  1302. spin_lock_irqsave(&ioc->FreeQlock, flags);
  1303. list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
  1304. spin_unlock_irqrestore(&ioc->FreeQlock, flags);
  1305. dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FreeChainBuffers (index %d)\n",
  1306. ioc->name, chain_idx));
  1307. /* handle next */
  1308. chain_idx = next;
  1309. }
  1310. return;
  1311. }
  1312. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1313. /*
  1314. * Reset Handling
  1315. */
  1316. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1317. /**
  1318. * mptscsih_IssueTaskMgmt - Generic send Task Management function.
  1319. * @hd: Pointer to MPT_SCSI_HOST structure
  1320. * @type: Task Management type
  1321. * @channel: channel number for task management
  1322. * @id: Logical Target ID for reset (if appropriate)
  1323. * @lun: Logical Unit for reset (if appropriate)
  1324. * @ctx2abort: Context for the task to be aborted (if appropriate)
  1325. * @timeout: timeout for task management control
  1326. *
  1327. * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
  1328. * or a non-interrupt thread. In the former, must not call schedule().
  1329. *
  1330. * Not all fields are meaningfull for all task types.
  1331. *
  1332. * Returns 0 for SUCCESS, or FAILED.
  1333. *
  1334. **/
  1335. int
  1336. mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, u64 lun,
  1337. int ctx2abort, ulong timeout)
  1338. {
  1339. MPT_FRAME_HDR *mf;
  1340. SCSITaskMgmt_t *pScsiTm;
  1341. int ii;
  1342. int retval;
  1343. MPT_ADAPTER *ioc = hd->ioc;
  1344. unsigned long timeleft;
  1345. u8 issue_hard_reset;
  1346. u32 ioc_raw_state;
  1347. unsigned long time_count;
  1348. issue_hard_reset = 0;
  1349. ioc_raw_state = mpt_GetIocState(ioc, 0);
  1350. if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
  1351. printk(MYIOC_s_WARN_FMT
  1352. "TaskMgmt type=%x: IOC Not operational (0x%x)!\n",
  1353. ioc->name, type, ioc_raw_state);
  1354. printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
  1355. ioc->name, __func__);
  1356. if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
  1357. printk(MYIOC_s_WARN_FMT "TaskMgmt HardReset "
  1358. "FAILED!!\n", ioc->name);
  1359. return 0;
  1360. }
  1361. /* DOORBELL ACTIVE check is not required if
  1362. * MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q is supported.
  1363. */
  1364. if (!((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q)
  1365. && (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) &&
  1366. (ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
  1367. printk(MYIOC_s_WARN_FMT
  1368. "TaskMgmt type=%x: ioc_state: "
  1369. "DOORBELL_ACTIVE (0x%x)!\n",
  1370. ioc->name, type, ioc_raw_state);
  1371. return FAILED;
  1372. }
  1373. mutex_lock(&ioc->taskmgmt_cmds.mutex);
  1374. if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
  1375. mf = NULL;
  1376. retval = FAILED;
  1377. goto out;
  1378. }
  1379. /* Return Fail to calling function if no message frames available.
  1380. */
  1381. if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
  1382. dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
  1383. "TaskMgmt no msg frames!!\n", ioc->name));
  1384. retval = FAILED;
  1385. mpt_clear_taskmgmt_in_progress_flag(ioc);
  1386. goto out;
  1387. }
  1388. dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
  1389. ioc->name, mf));
  1390. /* Format the Request
  1391. */
  1392. pScsiTm = (SCSITaskMgmt_t *) mf;
  1393. pScsiTm->TargetID = id;
  1394. pScsiTm->Bus = channel;
  1395. pScsiTm->ChainOffset = 0;
  1396. pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
  1397. pScsiTm->Reserved = 0;
  1398. pScsiTm->TaskType = type;
  1399. pScsiTm->Reserved1 = 0;
  1400. pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
  1401. ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
  1402. int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
  1403. for (ii=0; ii < 7; ii++)
  1404. pScsiTm->Reserved2[ii] = 0;
  1405. pScsiTm->TaskMsgContext = ctx2abort;
  1406. dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt: ctx2abort (0x%08x) "
  1407. "task_type = 0x%02X, timeout = %ld\n", ioc->name, ctx2abort,
  1408. type, timeout));
  1409. DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)pScsiTm);
  1410. INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
  1411. time_count = jiffies;
  1412. if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
  1413. (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
  1414. mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
  1415. else {
  1416. retval = mpt_send_handshake_request(ioc->TaskCtx, ioc,
  1417. sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP);
  1418. if (retval) {
  1419. dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
  1420. "TaskMgmt handshake FAILED!(mf=%p, rc=%d) \n",
  1421. ioc->name, mf, retval));
  1422. mpt_free_msg_frame(ioc, mf);
  1423. mpt_clear_taskmgmt_in_progress_flag(ioc);
  1424. goto out;
  1425. }
  1426. }
  1427. timeleft = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done,
  1428. timeout*HZ);
  1429. if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
  1430. retval = FAILED;
  1431. dtmprintk(ioc, printk(MYIOC_s_ERR_FMT
  1432. "TaskMgmt TIMED OUT!(mf=%p)\n", ioc->name, mf));
  1433. mpt_clear_taskmgmt_in_progress_flag(ioc);
  1434. if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
  1435. goto out;
  1436. issue_hard_reset = 1;
  1437. goto out;
  1438. }
  1439. retval = mptscsih_taskmgmt_reply(ioc, type,
  1440. (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply);
  1441. dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  1442. "TaskMgmt completed (%d seconds)\n",
  1443. ioc->name, jiffies_to_msecs(jiffies - time_count)/1000));
  1444. out:
  1445. CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
  1446. if (issue_hard_reset) {
  1447. printk(MYIOC_s_WARN_FMT
  1448. "Issuing Reset from %s!! doorbell=0x%08x\n",
  1449. ioc->name, __func__, mpt_GetIocState(ioc, 0));
  1450. retval = (ioc->bus_type == SAS) ?
  1451. mpt_HardResetHandler(ioc, CAN_SLEEP) :
  1452. mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
  1453. mpt_free_msg_frame(ioc, mf);
  1454. }
  1455. retval = (retval == 0) ? 0 : FAILED;
  1456. mutex_unlock(&ioc->taskmgmt_cmds.mutex);
  1457. return retval;
  1458. }
  1459. EXPORT_SYMBOL(mptscsih_IssueTaskMgmt);
  1460. static int
  1461. mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
  1462. {
  1463. switch (ioc->bus_type) {
  1464. case FC:
  1465. return 40;
  1466. case SAS:
  1467. return 30;
  1468. case SPI:
  1469. default:
  1470. return 10;
  1471. }
  1472. }
  1473. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1474. /**
  1475. * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
  1476. * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
  1477. *
  1478. * (linux scsi_host_template.eh_abort_handler routine)
  1479. *
  1480. * Returns SUCCESS or FAILED.
  1481. **/
  1482. int
  1483. mptscsih_abort(struct scsi_cmnd * SCpnt)
  1484. {
  1485. MPT_SCSI_HOST *hd;
  1486. MPT_FRAME_HDR *mf;
  1487. u32 ctx2abort;
  1488. int scpnt_idx;
  1489. int retval;
  1490. VirtDevice *vdevice;
  1491. MPT_ADAPTER *ioc;
  1492. /* If we can't locate our host adapter structure, return FAILED status.
  1493. */
  1494. if ((hd = shost_priv(SCpnt->device->host)) == NULL) {
  1495. SCpnt->result = DID_RESET << 16;
  1496. SCpnt->scsi_done(SCpnt);
  1497. printk(KERN_ERR MYNAM ": task abort: "
  1498. "can't locate host! (sc=%p)\n", SCpnt);
  1499. return FAILED;
  1500. }
  1501. ioc = hd->ioc;
  1502. printk(MYIOC_s_INFO_FMT "attempting task abort! (sc=%p)\n",
  1503. ioc->name, SCpnt);
  1504. scsi_print_command(SCpnt);
  1505. vdevice = SCpnt->device->hostdata;
  1506. if (!vdevice || !vdevice->vtarget) {
  1507. dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  1508. "task abort: device has been deleted (sc=%p)\n",
  1509. ioc->name, SCpnt));
  1510. SCpnt->result = DID_NO_CONNECT << 16;
  1511. SCpnt->scsi_done(SCpnt);
  1512. retval = SUCCESS;
  1513. goto out;
  1514. }
  1515. /* Task aborts are not supported for hidden raid components.
  1516. */
  1517. if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
  1518. dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  1519. "task abort: hidden raid component (sc=%p)\n",
  1520. ioc->name, SCpnt));
  1521. SCpnt->result = DID_RESET << 16;
  1522. retval = FAILED;
  1523. goto out;
  1524. }
  1525. /* Task aborts are not supported for volumes.
  1526. */
  1527. if (vdevice->vtarget->raidVolume) {
  1528. dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  1529. "task abort: raid volume (sc=%p)\n",
  1530. ioc->name, SCpnt));
  1531. SCpnt->result = DID_RESET << 16;
  1532. retval = FAILED;
  1533. goto out;
  1534. }
  1535. /* Find this command
  1536. */
  1537. if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(ioc, SCpnt)) < 0) {
  1538. /* Cmd not found in ScsiLookup.
  1539. * Do OS callback.
  1540. */
  1541. SCpnt->result = DID_RESET << 16;
  1542. dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: "
  1543. "Command not in the active list! (sc=%p)\n", ioc->name,
  1544. SCpnt));
  1545. retval = SUCCESS;
  1546. goto out;
  1547. }
  1548. if (ioc->timeouts < -1)
  1549. ioc->timeouts++;
  1550. if (mpt_fwfault_debug)
  1551. mpt_halt_firmware(ioc);
  1552. /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
  1553. * (the IO to be ABORT'd)
  1554. *
  1555. * NOTE: Since we do not byteswap MsgContext, we do not
  1556. * swap it here either. It is an opaque cookie to
  1557. * the controller, so it does not matter. -DaveM
  1558. */
  1559. mf = MPT_INDEX_2_MFPTR(ioc, scpnt_idx);
  1560. ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
  1561. retval = mptscsih_IssueTaskMgmt(hd,
  1562. MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
  1563. vdevice->vtarget->channel,
  1564. vdevice->vtarget->id, vdevice->lun,
  1565. ctx2abort, mptscsih_get_tm_timeout(ioc));
  1566. if (SCPNT_TO_LOOKUP_IDX(ioc, SCpnt) == scpnt_idx) {
  1567. dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  1568. "task abort: command still in active list! (sc=%p)\n",
  1569. ioc->name, SCpnt));
  1570. retval = FAILED;
  1571. } else {
  1572. dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  1573. "task abort: command cleared from active list! (sc=%p)\n",
  1574. ioc->name, SCpnt));
  1575. retval = SUCCESS;
  1576. }
  1577. out:
  1578. printk(MYIOC_s_INFO_FMT "task abort: %s (rv=%04x) (sc=%p)\n",
  1579. ioc->name, ((retval == SUCCESS) ? "SUCCESS" : "FAILED"), retval,
  1580. SCpnt);
  1581. return retval;
  1582. }
  1583. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1584. /**
  1585. * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
  1586. * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
  1587. *
  1588. * (linux scsi_host_template.eh_dev_reset_handler routine)
  1589. *
  1590. * Returns SUCCESS or FAILED.
  1591. **/
  1592. int
  1593. mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
  1594. {
  1595. MPT_SCSI_HOST *hd;
  1596. int retval;
  1597. VirtDevice *vdevice;
  1598. MPT_ADAPTER *ioc;
  1599. /* If we can't locate our host adapter structure, return FAILED status.
  1600. */
  1601. if ((hd = shost_priv(SCpnt->device->host)) == NULL){
  1602. printk(KERN_ERR MYNAM ": target reset: "
  1603. "Can't locate host! (sc=%p)\n", SCpnt);
  1604. return FAILED;
  1605. }
  1606. ioc = hd->ioc;
  1607. printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
  1608. ioc->name, SCpnt);
  1609. scsi_print_command(SCpnt);
  1610. vdevice = SCpnt->device->hostdata;
  1611. if (!vdevice || !vdevice->vtarget) {
  1612. retval = 0;
  1613. goto out;
  1614. }
  1615. /* Target reset to hidden raid component is not supported
  1616. */
  1617. if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
  1618. retval = FAILED;
  1619. goto out;
  1620. }
  1621. retval = mptscsih_IssueTaskMgmt(hd,
  1622. MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
  1623. vdevice->vtarget->channel,
  1624. vdevice->vtarget->id, 0, 0,
  1625. mptscsih_get_tm_timeout(ioc));
  1626. out:
  1627. printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
  1628. ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
  1629. if (retval == 0)
  1630. return SUCCESS;
  1631. else
  1632. return FAILED;
  1633. }
  1634. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1635. /**
  1636. * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
  1637. * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
  1638. *
  1639. * (linux scsi_host_template.eh_bus_reset_handler routine)
  1640. *
  1641. * Returns SUCCESS or FAILED.
  1642. **/
  1643. int
  1644. mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
  1645. {
  1646. MPT_SCSI_HOST *hd;
  1647. int retval;
  1648. VirtDevice *vdevice;
  1649. MPT_ADAPTER *ioc;
  1650. /* If we can't locate our host adapter structure, return FAILED status.
  1651. */
  1652. if ((hd = shost_priv(SCpnt->device->host)) == NULL){
  1653. printk(KERN_ERR MYNAM ": bus reset: "
  1654. "Can't locate host! (sc=%p)\n", SCpnt);
  1655. return FAILED;
  1656. }
  1657. ioc = hd->ioc;
  1658. printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
  1659. ioc->name, SCpnt);
  1660. scsi_print_command(SCpnt);
  1661. if (ioc->timeouts < -1)
  1662. ioc->timeouts++;
  1663. vdevice = SCpnt->device->hostdata;
  1664. if (!vdevice || !vdevice->vtarget)
  1665. return SUCCESS;
  1666. retval = mptscsih_IssueTaskMgmt(hd,
  1667. MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
  1668. vdevice->vtarget->channel, 0, 0, 0,
  1669. mptscsih_get_tm_timeout(ioc));
  1670. printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
  1671. ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
  1672. if (retval == 0)
  1673. return SUCCESS;
  1674. else
  1675. return FAILED;
  1676. }
  1677. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1678. /**
  1679. * mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
  1680. * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
  1681. *
  1682. * (linux scsi_host_template.eh_host_reset_handler routine)
  1683. *
  1684. * Returns SUCCESS or FAILED.
  1685. */
  1686. int
  1687. mptscsih_host_reset(struct scsi_cmnd *SCpnt)
  1688. {
  1689. MPT_SCSI_HOST * hd;
  1690. int status = SUCCESS;
  1691. MPT_ADAPTER *ioc;
  1692. int retval;
  1693. /* If we can't locate the host to reset, then we failed. */
  1694. if ((hd = shost_priv(SCpnt->device->host)) == NULL){
  1695. printk(KERN_ERR MYNAM ": host reset: "
  1696. "Can't locate host! (sc=%p)\n", SCpnt);
  1697. return FAILED;
  1698. }
  1699. /* make sure we have no outstanding commands at this stage */
  1700. mptscsih_flush_running_cmds(hd);
  1701. ioc = hd->ioc;
  1702. printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
  1703. ioc->name, SCpnt);
  1704. /* If our attempts to reset the host failed, then return a failed
  1705. * status. The host will be taken off line by the SCSI mid-layer.
  1706. */
  1707. retval = mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
  1708. if (retval < 0)
  1709. status = FAILED;
  1710. else
  1711. status = SUCCESS;
  1712. printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
  1713. ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
  1714. return status;
  1715. }
  1716. static int
  1717. mptscsih_taskmgmt_reply(MPT_ADAPTER *ioc, u8 type,
  1718. SCSITaskMgmtReply_t *pScsiTmReply)
  1719. {
  1720. u16 iocstatus;
  1721. u32 termination_count;
  1722. int retval;
  1723. if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
  1724. retval = FAILED;
  1725. goto out;
  1726. }
  1727. DBG_DUMP_TM_REPLY_FRAME(ioc, (u32 *)pScsiTmReply);
  1728. iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
  1729. termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
  1730. dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  1731. "TaskMgmt fw_channel = %d, fw_id = %d, task_type = 0x%02X,\n"
  1732. "\tiocstatus = 0x%04X, loginfo = 0x%08X, response_code = 0x%02X,\n"
  1733. "\tterm_cmnds = %d\n", ioc->name, pScsiTmReply->Bus,
  1734. pScsiTmReply->TargetID, type, le16_to_cpu(pScsiTmReply->IOCStatus),
  1735. le32_to_cpu(pScsiTmReply->IOCLogInfo), pScsiTmReply->ResponseCode,
  1736. termination_count));
  1737. if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
  1738. pScsiTmReply->ResponseCode)
  1739. mptscsih_taskmgmt_response_code(ioc,
  1740. pScsiTmReply->ResponseCode);
  1741. if (iocstatus == MPI_IOCSTATUS_SUCCESS) {
  1742. retval = 0;
  1743. goto out;
  1744. }
  1745. retval = FAILED;
  1746. if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
  1747. if (termination_count == 1)
  1748. retval = 0;
  1749. goto out;
  1750. }
  1751. if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
  1752. iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
  1753. retval = 0;
  1754. out:
  1755. return retval;
  1756. }
  1757. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1758. void
  1759. mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
  1760. {
  1761. char *desc;
  1762. switch (response_code) {
  1763. case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
  1764. desc = "The task completed.";
  1765. break;
  1766. case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
  1767. desc = "The IOC received an invalid frame status.";
  1768. break;
  1769. case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
  1770. desc = "The task type is not supported.";
  1771. break;
  1772. case MPI_SCSITASKMGMT_RSP_TM_FAILED:
  1773. desc = "The requested task failed.";
  1774. break;
  1775. case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
  1776. desc = "The task completed successfully.";
  1777. break;
  1778. case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
  1779. desc = "The LUN request is invalid.";
  1780. break;
  1781. case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
  1782. desc = "The task is in the IOC queue and has not been sent to target.";
  1783. break;
  1784. default:
  1785. desc = "unknown";
  1786. break;
  1787. }
  1788. printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
  1789. ioc->name, response_code, desc);
  1790. }
  1791. EXPORT_SYMBOL(mptscsih_taskmgmt_response_code);
  1792. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1793. /**
  1794. * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
  1795. * @ioc: Pointer to MPT_ADAPTER structure
  1796. * @mf: Pointer to SCSI task mgmt request frame
  1797. * @mr: Pointer to SCSI task mgmt reply frame
  1798. *
  1799. * This routine is called from mptbase.c::mpt_interrupt() at the completion
  1800. * of any SCSI task management request.
  1801. * This routine is registered with the MPT (base) driver at driver
  1802. * load/init time via the mpt_register() API call.
  1803. *
  1804. * Returns 1 indicating alloc'd request frame ptr should be freed.
  1805. **/
  1806. int
  1807. mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf,
  1808. MPT_FRAME_HDR *mr)
  1809. {
  1810. dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  1811. "TaskMgmt completed (mf=%p, mr=%p)\n", ioc->name, mf, mr));
  1812. ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
  1813. if (!mr)
  1814. goto out;
  1815. ioc->taskmgmt_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
  1816. memcpy(ioc->taskmgmt_cmds.reply, mr,
  1817. min(MPT_DEFAULT_FRAME_SIZE, 4 * mr->u.reply.MsgLength));
  1818. out:
  1819. if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
  1820. mpt_clear_taskmgmt_in_progress_flag(ioc);
  1821. ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
  1822. complete(&ioc->taskmgmt_cmds.done);
  1823. if (ioc->bus_type == SAS)
  1824. ioc->schedule_target_reset(ioc);
  1825. return 1;
  1826. }
  1827. return 0;
  1828. }
  1829. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1830. /*
  1831. * This is anyones guess quite frankly.
  1832. */
  1833. int
  1834. mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
  1835. sector_t capacity, int geom[])
  1836. {
  1837. int heads;
  1838. int sectors;
  1839. sector_t cylinders;
  1840. ulong dummy;
  1841. heads = 64;
  1842. sectors = 32;
  1843. dummy = heads * sectors;
  1844. cylinders = capacity;
  1845. sector_div(cylinders,dummy);
  1846. /*
  1847. * Handle extended translation size for logical drives
  1848. * > 1Gb
  1849. */
  1850. if ((ulong)capacity >= 0x200000) {
  1851. heads = 255;
  1852. sectors = 63;
  1853. dummy = heads * sectors;
  1854. cylinders = capacity;
  1855. sector_div(cylinders,dummy);
  1856. }
  1857. /* return result */
  1858. geom[0] = heads;
  1859. geom[1] = sectors;
  1860. geom[2] = cylinders;
  1861. return 0;
  1862. }
  1863. /* Search IOC page 3 to determine if this is hidden physical disk
  1864. *
  1865. */
  1866. int
  1867. mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
  1868. {
  1869. struct inactive_raid_component_info *component_info;
  1870. int i, j;
  1871. RaidPhysDiskPage1_t *phys_disk;
  1872. int rc = 0;
  1873. int num_paths;
  1874. if (!ioc->raid_data.pIocPg3)
  1875. goto out;
  1876. for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
  1877. if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
  1878. (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
  1879. rc = 1;
  1880. goto out;
  1881. }
  1882. }
  1883. if (ioc->bus_type != SAS)
  1884. goto out;
  1885. /*
  1886. * Check if dual path
  1887. */
  1888. for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
  1889. num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
  1890. ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
  1891. if (num_paths < 2)
  1892. continue;
  1893. phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
  1894. (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
  1895. if (!phys_disk)
  1896. continue;
  1897. if ((mpt_raid_phys_disk_pg1(ioc,
  1898. ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
  1899. phys_disk))) {
  1900. kfree(phys_disk);
  1901. continue;
  1902. }
  1903. for (j = 0; j < num_paths; j++) {
  1904. if ((phys_disk->Path[j].Flags &
  1905. MPI_RAID_PHYSDISK1_FLAG_INVALID))
  1906. continue;
  1907. if ((phys_disk->Path[j].Flags &
  1908. MPI_RAID_PHYSDISK1_FLAG_BROKEN))
  1909. continue;
  1910. if ((id == phys_disk->Path[j].PhysDiskID) &&
  1911. (channel == phys_disk->Path[j].PhysDiskBus)) {
  1912. rc = 1;
  1913. kfree(phys_disk);
  1914. goto out;
  1915. }
  1916. }
  1917. kfree(phys_disk);
  1918. }
  1919. /*
  1920. * Check inactive list for matching phys disks
  1921. */
  1922. if (list_empty(&ioc->raid_data.inactive_list))
  1923. goto out;
  1924. mutex_lock(&ioc->raid_data.inactive_list_mutex);
  1925. list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
  1926. list) {
  1927. if ((component_info->d.PhysDiskID == id) &&
  1928. (component_info->d.PhysDiskBus == channel))
  1929. rc = 1;
  1930. }
  1931. mutex_unlock(&ioc->raid_data.inactive_list_mutex);
  1932. out:
  1933. return rc;
  1934. }
  1935. EXPORT_SYMBOL(mptscsih_is_phys_disk);
  1936. u8
  1937. mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
  1938. {
  1939. struct inactive_raid_component_info *component_info;
  1940. int i, j;
  1941. RaidPhysDiskPage1_t *phys_disk;
  1942. int rc = -ENXIO;
  1943. int num_paths;
  1944. if (!ioc->raid_data.pIocPg3)
  1945. goto out;
  1946. for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
  1947. if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
  1948. (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
  1949. rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
  1950. goto out;
  1951. }
  1952. }
  1953. if (ioc->bus_type != SAS)
  1954. goto out;
  1955. /*
  1956. * Check if dual path
  1957. */
  1958. for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
  1959. num_paths = mpt_raid_phys_disk_get_num_paths(ioc,
  1960. ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum);
  1961. if (num_paths < 2)
  1962. continue;
  1963. phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) +
  1964. (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL);
  1965. if (!phys_disk)
  1966. continue;
  1967. if ((mpt_raid_phys_disk_pg1(ioc,
  1968. ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum,
  1969. phys_disk))) {
  1970. kfree(phys_disk);
  1971. continue;
  1972. }
  1973. for (j = 0; j < num_paths; j++) {
  1974. if ((phys_disk->Path[j].Flags &
  1975. MPI_RAID_PHYSDISK1_FLAG_INVALID))
  1976. continue;
  1977. if ((phys_disk->Path[j].Flags &
  1978. MPI_RAID_PHYSDISK1_FLAG_BROKEN))
  1979. continue;
  1980. if ((id == phys_disk->Path[j].PhysDiskID) &&
  1981. (channel == phys_disk->Path[j].PhysDiskBus)) {
  1982. rc = phys_disk->PhysDiskNum;
  1983. kfree(phys_disk);
  1984. goto out;
  1985. }
  1986. }
  1987. kfree(phys_disk);
  1988. }
  1989. /*
  1990. * Check inactive list for matching phys disks
  1991. */
  1992. if (list_empty(&ioc->raid_data.inactive_list))
  1993. goto out;
  1994. mutex_lock(&ioc->raid_data.inactive_list_mutex);
  1995. list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
  1996. list) {
  1997. if ((component_info->d.PhysDiskID == id) &&
  1998. (component_info->d.PhysDiskBus == channel))
  1999. rc = component_info->d.PhysDiskNum;
  2000. }
  2001. mutex_unlock(&ioc->raid_data.inactive_list_mutex);
  2002. out:
  2003. return rc;
  2004. }
  2005. EXPORT_SYMBOL(mptscsih_raid_id_to_num);
  2006. /*
  2007. * OS entry point to allow for host driver to free allocated memory
  2008. * Called if no device present or device being unloaded
  2009. */
  2010. void
  2011. mptscsih_slave_destroy(struct scsi_device *sdev)
  2012. {
  2013. struct Scsi_Host *host = sdev->host;
  2014. MPT_SCSI_HOST *hd = shost_priv(host);
  2015. VirtTarget *vtarget;
  2016. VirtDevice *vdevice;
  2017. struct scsi_target *starget;
  2018. starget = scsi_target(sdev);
  2019. vtarget = starget->hostdata;
  2020. vdevice = sdev->hostdata;
  2021. if (!vdevice)
  2022. return;
  2023. mptscsih_search_running_cmds(hd, vdevice);
  2024. vtarget->num_luns--;
  2025. mptscsih_synchronize_cache(hd, vdevice);
  2026. kfree(vdevice);
  2027. sdev->hostdata = NULL;
  2028. }
  2029. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2030. /*
  2031. * mptscsih_change_queue_depth - This function will set a devices queue depth
  2032. * @sdev: per scsi_device pointer
  2033. * @qdepth: requested queue depth
  2034. *
  2035. * Adding support for new 'change_queue_depth' api.
  2036. */
  2037. int
  2038. mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
  2039. {
  2040. MPT_SCSI_HOST *hd = shost_priv(sdev->host);
  2041. VirtTarget *vtarget;
  2042. struct scsi_target *starget;
  2043. int max_depth;
  2044. MPT_ADAPTER *ioc = hd->ioc;
  2045. starget = scsi_target(sdev);
  2046. vtarget = starget->hostdata;
  2047. if (ioc->bus_type == SPI) {
  2048. if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
  2049. max_depth = 1;
  2050. else if (sdev->type == TYPE_DISK &&
  2051. vtarget->minSyncFactor <= MPT_ULTRA160)
  2052. max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
  2053. else
  2054. max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
  2055. } else
  2056. max_depth = ioc->sh->can_queue;
  2057. if (!sdev->tagged_supported)
  2058. max_depth = 1;
  2059. if (qdepth > max_depth)
  2060. qdepth = max_depth;
  2061. return scsi_change_queue_depth(sdev, qdepth);
  2062. }
  2063. /*
  2064. * OS entry point to adjust the queue_depths on a per-device basis.
  2065. * Called once per device the bus scan. Use it to force the queue_depth
  2066. * member to 1 if a device does not support Q tags.
  2067. * Return non-zero if fails.
  2068. */
  2069. int
  2070. mptscsih_slave_configure(struct scsi_device *sdev)
  2071. {
  2072. struct Scsi_Host *sh = sdev->host;
  2073. VirtTarget *vtarget;
  2074. VirtDevice *vdevice;
  2075. struct scsi_target *starget;
  2076. MPT_SCSI_HOST *hd = shost_priv(sh);
  2077. MPT_ADAPTER *ioc = hd->ioc;
  2078. starget = scsi_target(sdev);
  2079. vtarget = starget->hostdata;
  2080. vdevice = sdev->hostdata;
  2081. dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  2082. "device @ %p, channel=%d, id=%d, lun=%llu\n",
  2083. ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
  2084. if (ioc->bus_type == SPI)
  2085. dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  2086. "sdtr %d wdtr %d ppr %d inq length=%d\n",
  2087. ioc->name, sdev->sdtr, sdev->wdtr,
  2088. sdev->ppr, sdev->inquiry_len));
  2089. vdevice->configured_lun = 1;
  2090. dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  2091. "Queue depth=%d, tflags=%x\n",
  2092. ioc->name, sdev->queue_depth, vtarget->tflags));
  2093. if (ioc->bus_type == SPI)
  2094. dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  2095. "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
  2096. ioc->name, vtarget->negoFlags, vtarget->maxOffset,
  2097. vtarget->minSyncFactor));
  2098. mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
  2099. dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  2100. "tagged %d, simple %d\n",
  2101. ioc->name,sdev->tagged_supported, sdev->simple_tags));
  2102. blk_queue_dma_alignment (sdev->request_queue, 512 - 1);
  2103. return 0;
  2104. }
  2105. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2106. /*
  2107. * Private routines...
  2108. */
  2109. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2110. /* Utility function to copy sense data from the scsi_cmnd buffer
  2111. * to the FC and SCSI target structures.
  2112. *
  2113. */
  2114. static void
  2115. mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
  2116. {
  2117. VirtDevice *vdevice;
  2118. SCSIIORequest_t *pReq;
  2119. u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
  2120. MPT_ADAPTER *ioc = hd->ioc;
  2121. /* Get target structure
  2122. */
  2123. pReq = (SCSIIORequest_t *) mf;
  2124. vdevice = sc->device->hostdata;
  2125. if (sense_count) {
  2126. u8 *sense_data;
  2127. int req_index;
  2128. /* Copy the sense received into the scsi command block. */
  2129. req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
  2130. sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
  2131. memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
  2132. /* Log SMART data (asc = 0x5D, non-IM case only) if required.
  2133. */
  2134. if ((ioc->events) && (ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
  2135. if ((sense_data[12] == 0x5D) && (vdevice->vtarget->raidVolume == 0)) {
  2136. int idx;
  2137. idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
  2138. ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
  2139. ioc->events[idx].eventContext = ioc->eventContext;
  2140. ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
  2141. (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
  2142. (sc->device->channel << 8) | sc->device->id;
  2143. ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
  2144. ioc->eventContext++;
  2145. if (ioc->pcidev->vendor ==
  2146. PCI_VENDOR_ID_IBM) {
  2147. mptscsih_issue_sep_command(ioc,
  2148. vdevice->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
  2149. vdevice->vtarget->tflags |=
  2150. MPT_TARGET_FLAGS_LED_ON;
  2151. }
  2152. }
  2153. }
  2154. } else {
  2155. dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hmmm... SenseData len=0! (?)\n",
  2156. ioc->name));
  2157. }
  2158. }
  2159. /**
  2160. * mptscsih_get_scsi_lookup - retrieves scmd entry
  2161. * @ioc: Pointer to MPT_ADAPTER structure
  2162. * @i: index into the array
  2163. *
  2164. * Returns the scsi_cmd pointer
  2165. */
  2166. struct scsi_cmnd *
  2167. mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i)
  2168. {
  2169. unsigned long flags;
  2170. struct scsi_cmnd *scmd;
  2171. spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
  2172. scmd = ioc->ScsiLookup[i];
  2173. spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
  2174. return scmd;
  2175. }
  2176. EXPORT_SYMBOL(mptscsih_get_scsi_lookup);
  2177. /**
  2178. * mptscsih_getclear_scsi_lookup - retrieves and clears scmd entry from ScsiLookup[] array list
  2179. * @ioc: Pointer to MPT_ADAPTER structure
  2180. * @i: index into the array
  2181. *
  2182. * Returns the scsi_cmd pointer
  2183. *
  2184. **/
  2185. static struct scsi_cmnd *
  2186. mptscsih_getclear_scsi_lookup(MPT_ADAPTER *ioc, int i)
  2187. {
  2188. unsigned long flags;
  2189. struct scsi_cmnd *scmd;
  2190. spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
  2191. scmd = ioc->ScsiLookup[i];
  2192. ioc->ScsiLookup[i] = NULL;
  2193. spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
  2194. return scmd;
  2195. }
  2196. /**
  2197. * mptscsih_set_scsi_lookup - write a scmd entry into the ScsiLookup[] array list
  2198. *
  2199. * @ioc: Pointer to MPT_ADAPTER structure
  2200. * @i: index into the array
  2201. * @scmd: scsi_cmnd pointer
  2202. *
  2203. **/
  2204. static void
  2205. mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd)
  2206. {
  2207. unsigned long flags;
  2208. spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
  2209. ioc->ScsiLookup[i] = scmd;
  2210. spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
  2211. }
  2212. /**
  2213. * SCPNT_TO_LOOKUP_IDX - searches for a given scmd in the ScsiLookup[] array list
  2214. * @ioc: Pointer to MPT_ADAPTER structure
  2215. * @sc: scsi_cmnd pointer
  2216. */
  2217. static int
  2218. SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc)
  2219. {
  2220. unsigned long flags;
  2221. int i, index=-1;
  2222. spin_lock_irqsave(&ioc->scsi_lookup_lock, flags);
  2223. for (i = 0; i < ioc->req_depth; i++) {
  2224. if (ioc->ScsiLookup[i] == sc) {
  2225. index = i;
  2226. goto out;
  2227. }
  2228. }
  2229. out:
  2230. spin_unlock_irqrestore(&ioc->scsi_lookup_lock, flags);
  2231. return index;
  2232. }
  2233. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2234. int
  2235. mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
  2236. {
  2237. MPT_SCSI_HOST *hd;
  2238. if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL)
  2239. return 0;
  2240. hd = shost_priv(ioc->sh);
  2241. switch (reset_phase) {
  2242. case MPT_IOC_SETUP_RESET:
  2243. dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  2244. "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
  2245. break;
  2246. case MPT_IOC_PRE_RESET:
  2247. dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  2248. "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
  2249. mptscsih_flush_running_cmds(hd);
  2250. break;
  2251. case MPT_IOC_POST_RESET:
  2252. dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  2253. "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
  2254. if (ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING) {
  2255. ioc->internal_cmds.status |=
  2256. MPT_MGMT_STATUS_DID_IOCRESET;
  2257. complete(&ioc->internal_cmds.done);
  2258. }
  2259. break;
  2260. default:
  2261. break;
  2262. }
  2263. return 1; /* currently means nothing really */
  2264. }
  2265. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2266. int
  2267. mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
  2268. {
  2269. u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
  2270. devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  2271. "MPT event (=%02Xh) routed to SCSI host driver!\n",
  2272. ioc->name, event));
  2273. if ((event == MPI_EVENT_IOC_BUS_RESET ||
  2274. event == MPI_EVENT_EXT_BUS_RESET) &&
  2275. (ioc->bus_type == SPI) && (ioc->soft_resets < -1))
  2276. ioc->soft_resets++;
  2277. return 1; /* currently means nothing really */
  2278. }
  2279. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2280. /*
  2281. * Bus Scan and Domain Validation functionality ...
  2282. */
  2283. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2284. /*
  2285. * mptscsih_scandv_complete - Scan and DV callback routine registered
  2286. * to Fustion MPT (base) driver.
  2287. *
  2288. * @ioc: Pointer to MPT_ADAPTER structure
  2289. * @mf: Pointer to original MPT request frame
  2290. * @mr: Pointer to MPT reply frame (NULL if TurboReply)
  2291. *
  2292. * This routine is called from mpt.c::mpt_interrupt() at the completion
  2293. * of any SCSI IO request.
  2294. * This routine is registered with the Fusion MPT (base) driver at driver
  2295. * load/init time via the mpt_register() API call.
  2296. *
  2297. * Returns 1 indicating alloc'd request frame ptr should be freed.
  2298. *
  2299. * Remark: Sets a completion code and (possibly) saves sense data
  2300. * in the IOC member localReply structure.
  2301. * Used ONLY for DV and other internal commands.
  2302. */
  2303. int
  2304. mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
  2305. MPT_FRAME_HDR *reply)
  2306. {
  2307. SCSIIORequest_t *pReq;
  2308. SCSIIOReply_t *pReply;
  2309. u8 cmd;
  2310. u16 req_idx;
  2311. u8 *sense_data;
  2312. int sz;
  2313. ioc->internal_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
  2314. ioc->internal_cmds.completion_code = MPT_SCANDV_GOOD;
  2315. if (!reply)
  2316. goto out;
  2317. pReply = (SCSIIOReply_t *) reply;
  2318. pReq = (SCSIIORequest_t *) req;
  2319. ioc->internal_cmds.completion_code =
  2320. mptscsih_get_completion_code(ioc, req, reply);
  2321. ioc->internal_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
  2322. memcpy(ioc->internal_cmds.reply, reply,
  2323. min(MPT_DEFAULT_FRAME_SIZE, 4 * reply->u.reply.MsgLength));
  2324. cmd = reply->u.hdr.Function;
  2325. if (((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
  2326. (cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) &&
  2327. (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)) {
  2328. req_idx = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
  2329. sense_data = ((u8 *)ioc->sense_buf_pool +
  2330. (req_idx * MPT_SENSE_BUFFER_ALLOC));
  2331. sz = min_t(int, pReq->SenseBufferLength,
  2332. MPT_SENSE_BUFFER_ALLOC);
  2333. memcpy(ioc->internal_cmds.sense, sense_data, sz);
  2334. }
  2335. out:
  2336. if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_PENDING))
  2337. return 0;
  2338. ioc->internal_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
  2339. complete(&ioc->internal_cmds.done);
  2340. return 1;
  2341. }
  2342. /**
  2343. * mptscsih_get_completion_code - get completion code from MPT request
  2344. * @ioc: Pointer to MPT_ADAPTER structure
  2345. * @req: Pointer to original MPT request frame
  2346. * @reply: Pointer to MPT reply frame (NULL if TurboReply)
  2347. *
  2348. **/
  2349. static int
  2350. mptscsih_get_completion_code(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
  2351. MPT_FRAME_HDR *reply)
  2352. {
  2353. SCSIIOReply_t *pReply;
  2354. MpiRaidActionReply_t *pr;
  2355. u8 scsi_status;
  2356. u16 status;
  2357. int completion_code;
  2358. pReply = (SCSIIOReply_t *)reply;
  2359. status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
  2360. scsi_status = pReply->SCSIStatus;
  2361. devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  2362. "IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh,"
  2363. "IOCLogInfo=%08xh\n", ioc->name, status, pReply->SCSIState,
  2364. scsi_status, le32_to_cpu(pReply->IOCLogInfo)));
  2365. switch (status) {
  2366. case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
  2367. completion_code = MPT_SCANDV_SELECTION_TIMEOUT;
  2368. break;
  2369. case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
  2370. case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
  2371. case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
  2372. case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
  2373. completion_code = MPT_SCANDV_DID_RESET;
  2374. break;
  2375. case MPI_IOCSTATUS_BUSY:
  2376. case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:
  2377. completion_code = MPT_SCANDV_BUSY;
  2378. break;
  2379. case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
  2380. case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
  2381. case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
  2382. if (pReply->Function == MPI_FUNCTION_CONFIG) {
  2383. completion_code = MPT_SCANDV_GOOD;
  2384. } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
  2385. pr = (MpiRaidActionReply_t *)reply;
  2386. if (le16_to_cpu(pr->ActionStatus) ==
  2387. MPI_RAID_ACTION_ASTATUS_SUCCESS)
  2388. completion_code = MPT_SCANDV_GOOD;
  2389. else
  2390. completion_code = MPT_SCANDV_SOME_ERROR;
  2391. } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)
  2392. completion_code = MPT_SCANDV_SENSE;
  2393. else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
  2394. if (req->u.scsireq.CDB[0] == INQUIRY)
  2395. completion_code = MPT_SCANDV_ISSUE_SENSE;
  2396. else
  2397. completion_code = MPT_SCANDV_DID_RESET;
  2398. } else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
  2399. completion_code = MPT_SCANDV_DID_RESET;
  2400. else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
  2401. completion_code = MPT_SCANDV_DID_RESET;
  2402. else if (scsi_status == MPI_SCSI_STATUS_BUSY)
  2403. completion_code = MPT_SCANDV_BUSY;
  2404. else
  2405. completion_code = MPT_SCANDV_GOOD;
  2406. break;
  2407. case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
  2408. if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
  2409. completion_code = MPT_SCANDV_DID_RESET;
  2410. else
  2411. completion_code = MPT_SCANDV_SOME_ERROR;
  2412. break;
  2413. default:
  2414. completion_code = MPT_SCANDV_SOME_ERROR;
  2415. break;
  2416. } /* switch(status) */
  2417. devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  2418. " completionCode set to %08xh\n", ioc->name, completion_code));
  2419. return completion_code;
  2420. }
  2421. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2422. /**
  2423. * mptscsih_do_cmd - Do internal command.
  2424. * @hd: MPT_SCSI_HOST pointer
  2425. * @io: INTERNAL_CMD pointer.
  2426. *
  2427. * Issue the specified internally generated command and do command
  2428. * specific cleanup. For bus scan / DV only.
  2429. * NOTES: If command is Inquiry and status is good,
  2430. * initialize a target structure, save the data
  2431. *
  2432. * Remark: Single threaded access only.
  2433. *
  2434. * Return:
  2435. * < 0 if an illegal command or no resources
  2436. *
  2437. * 0 if good
  2438. *
  2439. * > 0 if command complete but some type of completion error.
  2440. */
  2441. static int
  2442. mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
  2443. {
  2444. MPT_FRAME_HDR *mf;
  2445. SCSIIORequest_t *pScsiReq;
  2446. int my_idx, ii, dir;
  2447. int timeout;
  2448. char cmdLen;
  2449. char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  2450. u8 cmd = io->cmd;
  2451. MPT_ADAPTER *ioc = hd->ioc;
  2452. int ret = 0;
  2453. unsigned long timeleft;
  2454. unsigned long flags;
  2455. /* don't send internal command during diag reset */
  2456. spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
  2457. if (ioc->ioc_reset_in_progress) {
  2458. spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
  2459. dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  2460. "%s: busy with host reset\n", ioc->name, __func__));
  2461. return MPT_SCANDV_BUSY;
  2462. }
  2463. spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
  2464. mutex_lock(&ioc->internal_cmds.mutex);
  2465. /* Set command specific information
  2466. */
  2467. switch (cmd) {
  2468. case INQUIRY:
  2469. cmdLen = 6;
  2470. dir = MPI_SCSIIO_CONTROL_READ;
  2471. CDB[0] = cmd;
  2472. CDB[4] = io->size;
  2473. timeout = 10;
  2474. break;
  2475. case TEST_UNIT_READY:
  2476. cmdLen = 6;
  2477. dir = MPI_SCSIIO_CONTROL_READ;
  2478. timeout = 10;
  2479. break;
  2480. case START_STOP:
  2481. cmdLen = 6;
  2482. dir = MPI_SCSIIO_CONTROL_READ;
  2483. CDB[0] = cmd;
  2484. CDB[4] = 1; /*Spin up the disk */
  2485. timeout = 15;
  2486. break;
  2487. case REQUEST_SENSE:
  2488. cmdLen = 6;
  2489. CDB[0] = cmd;
  2490. CDB[4] = io->size;
  2491. dir = MPI_SCSIIO_CONTROL_READ;
  2492. timeout = 10;
  2493. break;
  2494. case READ_BUFFER:
  2495. cmdLen = 10;
  2496. dir = MPI_SCSIIO_CONTROL_READ;
  2497. CDB[0] = cmd;
  2498. if (io->flags & MPT_ICFLAG_ECHO) {
  2499. CDB[1] = 0x0A;
  2500. } else {
  2501. CDB[1] = 0x02;
  2502. }
  2503. if (io->flags & MPT_ICFLAG_BUF_CAP) {
  2504. CDB[1] |= 0x01;
  2505. }
  2506. CDB[6] = (io->size >> 16) & 0xFF;
  2507. CDB[7] = (io->size >> 8) & 0xFF;
  2508. CDB[8] = io->size & 0xFF;
  2509. timeout = 10;
  2510. break;
  2511. case WRITE_BUFFER:
  2512. cmdLen = 10;
  2513. dir = MPI_SCSIIO_CONTROL_WRITE;
  2514. CDB[0] = cmd;
  2515. if (io->flags & MPT_ICFLAG_ECHO) {
  2516. CDB[1] = 0x0A;
  2517. } else {
  2518. CDB[1] = 0x02;
  2519. }
  2520. CDB[6] = (io->size >> 16) & 0xFF;
  2521. CDB[7] = (io->size >> 8) & 0xFF;
  2522. CDB[8] = io->size & 0xFF;
  2523. timeout = 10;
  2524. break;
  2525. case RESERVE:
  2526. cmdLen = 6;
  2527. dir = MPI_SCSIIO_CONTROL_READ;
  2528. CDB[0] = cmd;
  2529. timeout = 10;
  2530. break;
  2531. case RELEASE:
  2532. cmdLen = 6;
  2533. dir = MPI_SCSIIO_CONTROL_READ;
  2534. CDB[0] = cmd;
  2535. timeout = 10;
  2536. break;
  2537. case SYNCHRONIZE_CACHE:
  2538. cmdLen = 10;
  2539. dir = MPI_SCSIIO_CONTROL_READ;
  2540. CDB[0] = cmd;
  2541. // CDB[1] = 0x02; /* set immediate bit */
  2542. timeout = 10;
  2543. break;
  2544. default:
  2545. /* Error Case */
  2546. ret = -EFAULT;
  2547. goto out;
  2548. }
  2549. /* Get and Populate a free Frame
  2550. * MsgContext set in mpt_get_msg_frame call
  2551. */
  2552. if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
  2553. dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: No msg frames!\n",
  2554. ioc->name, __func__));
  2555. ret = MPT_SCANDV_BUSY;
  2556. goto out;
  2557. }
  2558. pScsiReq = (SCSIIORequest_t *) mf;
  2559. /* Get the request index */
  2560. my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
  2561. ADD_INDEX_LOG(my_idx); /* for debug */
  2562. if (io->flags & MPT_ICFLAG_PHYS_DISK) {
  2563. pScsiReq->TargetID = io->physDiskNum;
  2564. pScsiReq->Bus = 0;
  2565. pScsiReq->ChainOffset = 0;
  2566. pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
  2567. } else {
  2568. pScsiReq->TargetID = io->id;
  2569. pScsiReq->Bus = io->channel;
  2570. pScsiReq->ChainOffset = 0;
  2571. pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
  2572. }
  2573. pScsiReq->CDBLength = cmdLen;
  2574. pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
  2575. pScsiReq->Reserved = 0;
  2576. pScsiReq->MsgFlags = mpt_msg_flags(ioc);
  2577. /* MsgContext set in mpt_get_msg_fram call */
  2578. int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
  2579. if (io->flags & MPT_ICFLAG_TAGGED_CMD)
  2580. pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
  2581. else
  2582. pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
  2583. if (cmd == REQUEST_SENSE) {
  2584. pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
  2585. devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  2586. "%s: Untagged! 0x%02x\n", ioc->name, __func__, cmd));
  2587. }
  2588. for (ii = 0; ii < 16; ii++)
  2589. pScsiReq->CDB[ii] = CDB[ii];
  2590. pScsiReq->DataLength = cpu_to_le32(io->size);
  2591. pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
  2592. + (my_idx * MPT_SENSE_BUFFER_ALLOC));
  2593. devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  2594. "%s: Sending Command 0x%02x for fw_channel=%d fw_id=%d lun=%llu\n",
  2595. ioc->name, __func__, cmd, io->channel, io->id, io->lun));
  2596. if (dir == MPI_SCSIIO_CONTROL_READ)
  2597. ioc->add_sge((char *) &pScsiReq->SGL,
  2598. MPT_SGE_FLAGS_SSIMPLE_READ | io->size, io->data_dma);
  2599. else
  2600. ioc->add_sge((char *) &pScsiReq->SGL,
  2601. MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size, io->data_dma);
  2602. INITIALIZE_MGMT_STATUS(ioc->internal_cmds.status)
  2603. mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
  2604. timeleft = wait_for_completion_timeout(&ioc->internal_cmds.done,
  2605. timeout*HZ);
  2606. if (!(ioc->internal_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
  2607. ret = MPT_SCANDV_DID_RESET;
  2608. dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
  2609. "%s: TIMED OUT for cmd=0x%02x\n", ioc->name, __func__,
  2610. cmd));
  2611. if (ioc->internal_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
  2612. mpt_free_msg_frame(ioc, mf);
  2613. goto out;
  2614. }
  2615. if (!timeleft) {
  2616. printk(MYIOC_s_WARN_FMT
  2617. "Issuing Reset from %s!! doorbell=0x%08xh"
  2618. " cmd=0x%02x\n",
  2619. ioc->name, __func__, mpt_GetIocState(ioc, 0),
  2620. cmd);
  2621. mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
  2622. mpt_free_msg_frame(ioc, mf);
  2623. }
  2624. goto out;
  2625. }
  2626. ret = ioc->internal_cmds.completion_code;
  2627. devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: success, rc=0x%02x\n",
  2628. ioc->name, __func__, ret));
  2629. out:
  2630. CLEAR_MGMT_STATUS(ioc->internal_cmds.status)
  2631. mutex_unlock(&ioc->internal_cmds.mutex);
  2632. return ret;
  2633. }
  2634. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2635. /**
  2636. * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
  2637. * @hd: Pointer to a SCSI HOST structure
  2638. * @vdevice: virtual target device
  2639. *
  2640. * Uses the ISR, but with special processing.
  2641. * MUST be single-threaded.
  2642. *
  2643. */
  2644. static void
  2645. mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
  2646. {
  2647. INTERNAL_CMD iocmd;
  2648. /* Ignore hidden raid components, this is handled when the command
  2649. * is sent to the volume
  2650. */
  2651. if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
  2652. return;
  2653. if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
  2654. !vdevice->configured_lun)
  2655. return;
  2656. /* Following parameters will not change
  2657. * in this routine.
  2658. */
  2659. iocmd.cmd = SYNCHRONIZE_CACHE;
  2660. iocmd.flags = 0;
  2661. iocmd.physDiskNum = -1;
  2662. iocmd.data = NULL;
  2663. iocmd.data_dma = -1;
  2664. iocmd.size = 0;
  2665. iocmd.rsvd = iocmd.rsvd2 = 0;
  2666. iocmd.channel = vdevice->vtarget->channel;
  2667. iocmd.id = vdevice->vtarget->id;
  2668. iocmd.lun = vdevice->lun;
  2669. mptscsih_do_cmd(hd, &iocmd);
  2670. }
  2671. static ssize_t
  2672. mptscsih_version_fw_show(struct device *dev, struct device_attribute *attr,
  2673. char *buf)
  2674. {
  2675. struct Scsi_Host *host = class_to_shost(dev);
  2676. MPT_SCSI_HOST *hd = shost_priv(host);
  2677. MPT_ADAPTER *ioc = hd->ioc;
  2678. return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
  2679. (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
  2680. (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
  2681. (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
  2682. ioc->facts.FWVersion.Word & 0x000000FF);
  2683. }
  2684. static DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
  2685. static ssize_t
  2686. mptscsih_version_bios_show(struct device *dev, struct device_attribute *attr,
  2687. char *buf)
  2688. {
  2689. struct Scsi_Host *host = class_to_shost(dev);
  2690. MPT_SCSI_HOST *hd = shost_priv(host);
  2691. MPT_ADAPTER *ioc = hd->ioc;
  2692. return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
  2693. (ioc->biosVersion & 0xFF000000) >> 24,
  2694. (ioc->biosVersion & 0x00FF0000) >> 16,
  2695. (ioc->biosVersion & 0x0000FF00) >> 8,
  2696. ioc->biosVersion & 0x000000FF);
  2697. }
  2698. static DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
  2699. static ssize_t
  2700. mptscsih_version_mpi_show(struct device *dev, struct device_attribute *attr,
  2701. char *buf)
  2702. {
  2703. struct Scsi_Host *host = class_to_shost(dev);
  2704. MPT_SCSI_HOST *hd = shost_priv(host);
  2705. MPT_ADAPTER *ioc = hd->ioc;
  2706. return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
  2707. }
  2708. static DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
  2709. static ssize_t
  2710. mptscsih_version_product_show(struct device *dev,
  2711. struct device_attribute *attr,
  2712. char *buf)
  2713. {
  2714. struct Scsi_Host *host = class_to_shost(dev);
  2715. MPT_SCSI_HOST *hd = shost_priv(host);
  2716. MPT_ADAPTER *ioc = hd->ioc;
  2717. return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
  2718. }
  2719. static DEVICE_ATTR(version_product, S_IRUGO,
  2720. mptscsih_version_product_show, NULL);
  2721. static ssize_t
  2722. mptscsih_version_nvdata_persistent_show(struct device *dev,
  2723. struct device_attribute *attr,
  2724. char *buf)
  2725. {
  2726. struct Scsi_Host *host = class_to_shost(dev);
  2727. MPT_SCSI_HOST *hd = shost_priv(host);
  2728. MPT_ADAPTER *ioc = hd->ioc;
  2729. return snprintf(buf, PAGE_SIZE, "%02xh\n",
  2730. ioc->nvdata_version_persistent);
  2731. }
  2732. static DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
  2733. mptscsih_version_nvdata_persistent_show, NULL);
  2734. static ssize_t
  2735. mptscsih_version_nvdata_default_show(struct device *dev,
  2736. struct device_attribute *attr, char *buf)
  2737. {
  2738. struct Scsi_Host *host = class_to_shost(dev);
  2739. MPT_SCSI_HOST *hd = shost_priv(host);
  2740. MPT_ADAPTER *ioc = hd->ioc;
  2741. return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
  2742. }
  2743. static DEVICE_ATTR(version_nvdata_default, S_IRUGO,
  2744. mptscsih_version_nvdata_default_show, NULL);
  2745. static ssize_t
  2746. mptscsih_board_name_show(struct device *dev, struct device_attribute *attr,
  2747. char *buf)
  2748. {
  2749. struct Scsi_Host *host = class_to_shost(dev);
  2750. MPT_SCSI_HOST *hd = shost_priv(host);
  2751. MPT_ADAPTER *ioc = hd->ioc;
  2752. return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
  2753. }
  2754. static DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
  2755. static ssize_t
  2756. mptscsih_board_assembly_show(struct device *dev,
  2757. struct device_attribute *attr, char *buf)
  2758. {
  2759. struct Scsi_Host *host = class_to_shost(dev);
  2760. MPT_SCSI_HOST *hd = shost_priv(host);
  2761. MPT_ADAPTER *ioc = hd->ioc;
  2762. return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
  2763. }
  2764. static DEVICE_ATTR(board_assembly, S_IRUGO,
  2765. mptscsih_board_assembly_show, NULL);
  2766. static ssize_t
  2767. mptscsih_board_tracer_show(struct device *dev, struct device_attribute *attr,
  2768. char *buf)
  2769. {
  2770. struct Scsi_Host *host = class_to_shost(dev);
  2771. MPT_SCSI_HOST *hd = shost_priv(host);
  2772. MPT_ADAPTER *ioc = hd->ioc;
  2773. return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
  2774. }
  2775. static DEVICE_ATTR(board_tracer, S_IRUGO,
  2776. mptscsih_board_tracer_show, NULL);
  2777. static ssize_t
  2778. mptscsih_io_delay_show(struct device *dev, struct device_attribute *attr,
  2779. char *buf)
  2780. {
  2781. struct Scsi_Host *host = class_to_shost(dev);
  2782. MPT_SCSI_HOST *hd = shost_priv(host);
  2783. MPT_ADAPTER *ioc = hd->ioc;
  2784. return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
  2785. }
  2786. static DEVICE_ATTR(io_delay, S_IRUGO,
  2787. mptscsih_io_delay_show, NULL);
  2788. static ssize_t
  2789. mptscsih_device_delay_show(struct device *dev, struct device_attribute *attr,
  2790. char *buf)
  2791. {
  2792. struct Scsi_Host *host = class_to_shost(dev);
  2793. MPT_SCSI_HOST *hd = shost_priv(host);
  2794. MPT_ADAPTER *ioc = hd->ioc;
  2795. return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
  2796. }
  2797. static DEVICE_ATTR(device_delay, S_IRUGO,
  2798. mptscsih_device_delay_show, NULL);
  2799. static ssize_t
  2800. mptscsih_debug_level_show(struct device *dev, struct device_attribute *attr,
  2801. char *buf)
  2802. {
  2803. struct Scsi_Host *host = class_to_shost(dev);
  2804. MPT_SCSI_HOST *hd = shost_priv(host);
  2805. MPT_ADAPTER *ioc = hd->ioc;
  2806. return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->debug_level);
  2807. }
  2808. static ssize_t
  2809. mptscsih_debug_level_store(struct device *dev, struct device_attribute *attr,
  2810. const char *buf, size_t count)
  2811. {
  2812. struct Scsi_Host *host = class_to_shost(dev);
  2813. MPT_SCSI_HOST *hd = shost_priv(host);
  2814. MPT_ADAPTER *ioc = hd->ioc;
  2815. int val = 0;
  2816. if (sscanf(buf, "%x", &val) != 1)
  2817. return -EINVAL;
  2818. ioc->debug_level = val;
  2819. printk(MYIOC_s_INFO_FMT "debug_level=%08xh\n",
  2820. ioc->name, ioc->debug_level);
  2821. return strlen(buf);
  2822. }
  2823. static DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
  2824. mptscsih_debug_level_show, mptscsih_debug_level_store);
  2825. struct device_attribute *mptscsih_host_attrs[] = {
  2826. &dev_attr_version_fw,
  2827. &dev_attr_version_bios,
  2828. &dev_attr_version_mpi,
  2829. &dev_attr_version_product,
  2830. &dev_attr_version_nvdata_persistent,
  2831. &dev_attr_version_nvdata_default,
  2832. &dev_attr_board_name,
  2833. &dev_attr_board_assembly,
  2834. &dev_attr_board_tracer,
  2835. &dev_attr_io_delay,
  2836. &dev_attr_device_delay,
  2837. &dev_attr_debug_level,
  2838. NULL,
  2839. };
  2840. EXPORT_SYMBOL(mptscsih_host_attrs);
  2841. EXPORT_SYMBOL(mptscsih_remove);
  2842. EXPORT_SYMBOL(mptscsih_shutdown);
  2843. #ifdef CONFIG_PM
  2844. EXPORT_SYMBOL(mptscsih_suspend);
  2845. EXPORT_SYMBOL(mptscsih_resume);
  2846. #endif
  2847. EXPORT_SYMBOL(mptscsih_show_info);
  2848. EXPORT_SYMBOL(mptscsih_info);
  2849. EXPORT_SYMBOL(mptscsih_qcmd);
  2850. EXPORT_SYMBOL(mptscsih_slave_destroy);
  2851. EXPORT_SYMBOL(mptscsih_slave_configure);
  2852. EXPORT_SYMBOL(mptscsih_abort);
  2853. EXPORT_SYMBOL(mptscsih_dev_reset);
  2854. EXPORT_SYMBOL(mptscsih_bus_reset);
  2855. EXPORT_SYMBOL(mptscsih_host_reset);
  2856. EXPORT_SYMBOL(mptscsih_bios_param);
  2857. EXPORT_SYMBOL(mptscsih_io_done);
  2858. EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
  2859. EXPORT_SYMBOL(mptscsih_scandv_complete);
  2860. EXPORT_SYMBOL(mptscsih_event_process);
  2861. EXPORT_SYMBOL(mptscsih_ioc_reset);
  2862. EXPORT_SYMBOL(mptscsih_change_queue_depth);
  2863. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/