mptscsih.c 88 KB

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