mptscsih.c 154 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624
  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-2005 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. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  63. #define my_NAME "Fusion MPT SCSI Host driver"
  64. #define my_VERSION MPT_LINUX_VERSION_COMMON
  65. #define MYNAM "mptscsih"
  66. MODULE_AUTHOR(MODULEAUTHOR);
  67. MODULE_DESCRIPTION(my_NAME);
  68. MODULE_LICENSE("GPL");
  69. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  70. typedef struct _BIG_SENSE_BUF {
  71. u8 data[MPT_SENSE_BUFFER_ALLOC];
  72. } BIG_SENSE_BUF;
  73. #define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */
  74. #define MPT_SCANDV_DID_RESET (0x00000001)
  75. #define MPT_SCANDV_SENSE (0x00000002)
  76. #define MPT_SCANDV_SOME_ERROR (0x00000004)
  77. #define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008)
  78. #define MPT_SCANDV_ISSUE_SENSE (0x00000010)
  79. #define MPT_SCANDV_FALLBACK (0x00000020)
  80. #define MPT_SCANDV_MAX_RETRIES (10)
  81. #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
  82. #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
  83. #define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */
  84. #define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */
  85. #define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */
  86. #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
  87. #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
  88. typedef struct _internal_cmd {
  89. char *data; /* data pointer */
  90. dma_addr_t data_dma; /* data dma address */
  91. int size; /* transfer size */
  92. u8 cmd; /* SCSI Op Code */
  93. u8 bus; /* bus number */
  94. u8 id; /* SCSI ID (virtual) */
  95. u8 lun;
  96. u8 flags; /* Bit Field - See above */
  97. u8 physDiskNum; /* Phys disk number, -1 else */
  98. u8 rsvd2;
  99. u8 rsvd;
  100. } INTERNAL_CMD;
  101. typedef struct _negoparms {
  102. u8 width;
  103. u8 offset;
  104. u8 factor;
  105. u8 flags;
  106. } NEGOPARMS;
  107. typedef struct _dv_parameters {
  108. NEGOPARMS max;
  109. NEGOPARMS now;
  110. u8 cmd;
  111. u8 id;
  112. u16 pad1;
  113. } DVPARAMETERS;
  114. /*
  115. * Other private/forward protos...
  116. */
  117. int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
  118. static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
  119. int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
  120. static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
  121. SCSIIORequest_t *pReq, int req_idx);
  122. static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
  123. static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
  124. static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
  125. static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
  126. static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
  127. static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
  128. static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
  129. int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
  130. int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
  131. static void mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen);
  132. static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, char byte56);
  133. static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
  134. static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc);
  135. static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
  136. static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
  137. int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
  138. static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
  139. static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
  140. static void mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget);
  141. static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
  142. static struct work_struct mptscsih_persistTask;
  143. #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
  144. static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
  145. static void mptscsih_domainValidation(void *hd);
  146. static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
  147. static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
  148. static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
  149. static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
  150. static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id);
  151. static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc);
  152. #endif
  153. void mptscsih_remove(struct pci_dev *);
  154. void mptscsih_shutdown(struct pci_dev *);
  155. #ifdef CONFIG_PM
  156. int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
  157. int mptscsih_resume(struct pci_dev *pdev);
  158. #endif
  159. #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
  160. #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
  161. /*
  162. * Domain Validation task structure
  163. */
  164. static DEFINE_SPINLOCK(dvtaskQ_lock);
  165. static int dvtaskQ_active = 0;
  166. static int dvtaskQ_release = 0;
  167. static struct work_struct dvTaskQ_task;
  168. #endif
  169. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  170. /**
  171. * mptscsih_add_sge - Place a simple SGE at address pAddr.
  172. * @pAddr: virtual address for SGE
  173. * @flagslength: SGE flags and data transfer length
  174. * @dma_addr: Physical address
  175. *
  176. * This routine places a MPT request frame back on the MPT adapter's
  177. * FreeQ.
  178. */
  179. static inline void
  180. mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
  181. {
  182. if (sizeof(dma_addr_t) == sizeof(u64)) {
  183. SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
  184. u32 tmp = dma_addr & 0xFFFFFFFF;
  185. pSge->FlagsLength = cpu_to_le32(flagslength);
  186. pSge->Address.Low = cpu_to_le32(tmp);
  187. tmp = (u32) ((u64)dma_addr >> 32);
  188. pSge->Address.High = cpu_to_le32(tmp);
  189. } else {
  190. SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
  191. pSge->FlagsLength = cpu_to_le32(flagslength);
  192. pSge->Address = cpu_to_le32(dma_addr);
  193. }
  194. } /* mptscsih_add_sge() */
  195. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  196. /**
  197. * mptscsih_add_chain - Place a chain SGE at address pAddr.
  198. * @pAddr: virtual address for SGE
  199. * @next: nextChainOffset value (u32's)
  200. * @length: length of next SGL segment
  201. * @dma_addr: Physical address
  202. *
  203. * This routine places a MPT request frame back on the MPT adapter's
  204. * FreeQ.
  205. */
  206. static inline void
  207. mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
  208. {
  209. if (sizeof(dma_addr_t) == sizeof(u64)) {
  210. SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
  211. u32 tmp = dma_addr & 0xFFFFFFFF;
  212. pChain->Length = cpu_to_le16(length);
  213. pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
  214. pChain->NextChainOffset = next;
  215. pChain->Address.Low = cpu_to_le32(tmp);
  216. tmp = (u32) ((u64)dma_addr >> 32);
  217. pChain->Address.High = cpu_to_le32(tmp);
  218. } else {
  219. SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
  220. pChain->Length = cpu_to_le16(length);
  221. pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
  222. pChain->NextChainOffset = next;
  223. pChain->Address = cpu_to_le32(dma_addr);
  224. }
  225. } /* mptscsih_add_chain() */
  226. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  227. /*
  228. * mptscsih_getFreeChainBuffer - Function to get a free chain
  229. * from the MPT_SCSI_HOST FreeChainQ.
  230. * @ioc: Pointer to MPT_ADAPTER structure
  231. * @req_idx: Index of the SCSI IO request frame. (output)
  232. *
  233. * return SUCCESS or FAILED
  234. */
  235. static inline int
  236. mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
  237. {
  238. MPT_FRAME_HDR *chainBuf;
  239. unsigned long flags;
  240. int rc;
  241. int chain_idx;
  242. dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
  243. ioc->name));
  244. spin_lock_irqsave(&ioc->FreeQlock, flags);
  245. if (!list_empty(&ioc->FreeChainQ)) {
  246. int offset;
  247. chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
  248. u.frame.linkage.list);
  249. list_del(&chainBuf->u.frame.linkage.list);
  250. offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
  251. chain_idx = offset / ioc->req_sz;
  252. rc = SUCCESS;
  253. dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
  254. ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
  255. } else {
  256. rc = FAILED;
  257. chain_idx = MPT_HOST_NO_CHAIN;
  258. dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n",
  259. ioc->name));
  260. }
  261. spin_unlock_irqrestore(&ioc->FreeQlock, flags);
  262. *retIndex = chain_idx;
  263. return rc;
  264. } /* mptscsih_getFreeChainBuffer() */
  265. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  266. /*
  267. * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
  268. * SCSIIORequest_t Message Frame.
  269. * @ioc: Pointer to MPT_ADAPTER structure
  270. * @SCpnt: Pointer to scsi_cmnd structure
  271. * @pReq: Pointer to SCSIIORequest_t structure
  272. *
  273. * Returns ...
  274. */
  275. static int
  276. mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
  277. SCSIIORequest_t *pReq, int req_idx)
  278. {
  279. char *psge;
  280. char *chainSge;
  281. struct scatterlist *sg;
  282. int frm_sz;
  283. int sges_left, sg_done;
  284. int chain_idx = MPT_HOST_NO_CHAIN;
  285. int sgeOffset;
  286. int numSgeSlots, numSgeThisFrame;
  287. u32 sgflags, sgdir, thisxfer = 0;
  288. int chain_dma_off = 0;
  289. int newIndex;
  290. int ii;
  291. dma_addr_t v2;
  292. u32 RequestNB;
  293. sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
  294. if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
  295. sgdir = MPT_TRANSFER_HOST_TO_IOC;
  296. } else {
  297. sgdir = MPT_TRANSFER_IOC_TO_HOST;
  298. }
  299. psge = (char *) &pReq->SGL;
  300. frm_sz = ioc->req_sz;
  301. /* Map the data portion, if any.
  302. * sges_left = 0 if no data transfer.
  303. */
  304. if ( (sges_left = SCpnt->use_sg) ) {
  305. sges_left = pci_map_sg(ioc->pcidev,
  306. (struct scatterlist *) SCpnt->request_buffer,
  307. SCpnt->use_sg,
  308. SCpnt->sc_data_direction);
  309. if (sges_left == 0)
  310. return FAILED;
  311. } else if (SCpnt->request_bufflen) {
  312. SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
  313. SCpnt->request_buffer,
  314. SCpnt->request_bufflen,
  315. SCpnt->sc_data_direction);
  316. dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
  317. ioc->name, SCpnt, SCpnt->request_bufflen));
  318. mptscsih_add_sge((char *) &pReq->SGL,
  319. 0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
  320. SCpnt->SCp.dma_handle);
  321. return SUCCESS;
  322. }
  323. /* Handle the SG case.
  324. */
  325. sg = (struct scatterlist *) SCpnt->request_buffer;
  326. sg_done = 0;
  327. sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
  328. chainSge = NULL;
  329. /* Prior to entering this loop - the following must be set
  330. * current MF: sgeOffset (bytes)
  331. * chainSge (Null if original MF is not a chain buffer)
  332. * sg_done (num SGE done for this MF)
  333. */
  334. nextSGEset:
  335. numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
  336. numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
  337. sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
  338. /* Get first (num - 1) SG elements
  339. * Skip any SG entries with a length of 0
  340. * NOTE: at finish, sg and psge pointed to NEXT data/location positions
  341. */
  342. for (ii=0; ii < (numSgeThisFrame-1); ii++) {
  343. thisxfer = sg_dma_len(sg);
  344. if (thisxfer == 0) {
  345. sg ++; /* Get next SG element from the OS */
  346. sg_done++;
  347. continue;
  348. }
  349. v2 = sg_dma_address(sg);
  350. mptscsih_add_sge(psge, sgflags | thisxfer, v2);
  351. sg++; /* Get next SG element from the OS */
  352. psge += (sizeof(u32) + sizeof(dma_addr_t));
  353. sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
  354. sg_done++;
  355. }
  356. if (numSgeThisFrame == sges_left) {
  357. /* Add last element, end of buffer and end of list flags.
  358. */
  359. sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
  360. MPT_SGE_FLAGS_END_OF_BUFFER |
  361. MPT_SGE_FLAGS_END_OF_LIST;
  362. /* Add last SGE and set termination flags.
  363. * Note: Last SGE may have a length of 0 - which should be ok.
  364. */
  365. thisxfer = sg_dma_len(sg);
  366. v2 = sg_dma_address(sg);
  367. mptscsih_add_sge(psge, sgflags | thisxfer, v2);
  368. /*
  369. sg++;
  370. psge += (sizeof(u32) + sizeof(dma_addr_t));
  371. */
  372. sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
  373. sg_done++;
  374. if (chainSge) {
  375. /* The current buffer is a chain buffer,
  376. * but there is not another one.
  377. * Update the chain element
  378. * Offset and Length fields.
  379. */
  380. mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
  381. } else {
  382. /* The current buffer is the original MF
  383. * and there is no Chain buffer.
  384. */
  385. pReq->ChainOffset = 0;
  386. RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
  387. dsgprintk((MYIOC_s_INFO_FMT
  388. "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
  389. ioc->RequestNB[req_idx] = RequestNB;
  390. }
  391. } else {
  392. /* At least one chain buffer is needed.
  393. * Complete the first MF
  394. * - last SGE element, set the LastElement bit
  395. * - set ChainOffset (words) for orig MF
  396. * (OR finish previous MF chain buffer)
  397. * - update MFStructPtr ChainIndex
  398. * - Populate chain element
  399. * Also
  400. * Loop until done.
  401. */
  402. dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
  403. ioc->name, sg_done));
  404. /* Set LAST_ELEMENT flag for last non-chain element
  405. * in the buffer. Since psge points at the NEXT
  406. * SGE element, go back one SGE element, update the flags
  407. * and reset the pointer. (Note: sgflags & thisxfer are already
  408. * set properly).
  409. */
  410. if (sg_done) {
  411. u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
  412. sgflags = le32_to_cpu(*ptmp);
  413. sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
  414. *ptmp = cpu_to_le32(sgflags);
  415. }
  416. if (chainSge) {
  417. /* The current buffer is a chain buffer.
  418. * chainSge points to the previous Chain Element.
  419. * Update its chain element Offset and Length (must
  420. * include chain element size) fields.
  421. * Old chain element is now complete.
  422. */
  423. u8 nextChain = (u8) (sgeOffset >> 2);
  424. sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
  425. mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
  426. } else {
  427. /* The original MF buffer requires a chain buffer -
  428. * set the offset.
  429. * Last element in this MF is a chain element.
  430. */
  431. pReq->ChainOffset = (u8) (sgeOffset >> 2);
  432. RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
  433. dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
  434. ioc->RequestNB[req_idx] = RequestNB;
  435. }
  436. sges_left -= sg_done;
  437. /* NOTE: psge points to the beginning of the chain element
  438. * in current buffer. Get a chain buffer.
  439. */
  440. if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
  441. dfailprintk((MYIOC_s_INFO_FMT
  442. "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
  443. ioc->name, pReq->CDB[0], SCpnt));
  444. return FAILED;
  445. }
  446. /* Update the tracking arrays.
  447. * If chainSge == NULL, update ReqToChain, else ChainToChain
  448. */
  449. if (chainSge) {
  450. ioc->ChainToChain[chain_idx] = newIndex;
  451. } else {
  452. ioc->ReqToChain[req_idx] = newIndex;
  453. }
  454. chain_idx = newIndex;
  455. chain_dma_off = ioc->req_sz * chain_idx;
  456. /* Populate the chainSGE for the current buffer.
  457. * - Set chain buffer pointer to psge and fill
  458. * out the Address and Flags fields.
  459. */
  460. chainSge = (char *) psge;
  461. dsgprintk((KERN_INFO " Current buff @ %p (index 0x%x)",
  462. psge, req_idx));
  463. /* Start the SGE for the next buffer
  464. */
  465. psge = (char *) (ioc->ChainBuffer + chain_dma_off);
  466. sgeOffset = 0;
  467. sg_done = 0;
  468. dsgprintk((KERN_INFO " Chain buff @ %p (index 0x%x)\n",
  469. psge, chain_idx));
  470. /* Start the SGE for the next buffer
  471. */
  472. goto nextSGEset;
  473. }
  474. return SUCCESS;
  475. } /* mptscsih_AddSGE() */
  476. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  477. /*
  478. * mptscsih_io_done - Main SCSI IO callback routine registered to
  479. * Fusion MPT (base) driver
  480. * @ioc: Pointer to MPT_ADAPTER structure
  481. * @mf: Pointer to original MPT request frame
  482. * @r: Pointer to MPT reply frame (NULL if TurboReply)
  483. *
  484. * This routine is called from mpt.c::mpt_interrupt() at the completion
  485. * of any SCSI IO request.
  486. * This routine is registered with the Fusion MPT (base) driver at driver
  487. * load/init time via the mpt_register() API call.
  488. *
  489. * Returns 1 indicating alloc'd request frame ptr should be freed.
  490. */
  491. int
  492. mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
  493. {
  494. struct scsi_cmnd *sc;
  495. MPT_SCSI_HOST *hd;
  496. SCSIIORequest_t *pScsiReq;
  497. SCSIIOReply_t *pScsiReply;
  498. u16 req_idx;
  499. hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
  500. req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
  501. sc = hd->ScsiLookup[req_idx];
  502. if (sc == NULL) {
  503. MPIHeader_t *hdr = (MPIHeader_t *)mf;
  504. /* Remark: writeSDP1 will use the ScsiDoneCtx
  505. * If a SCSI I/O cmd, device disabled by OS and
  506. * completion done. Cannot touch sc struct. Just free mem.
  507. */
  508. if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
  509. printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
  510. ioc->name);
  511. mptscsih_freeChainBuffers(ioc, req_idx);
  512. return 1;
  513. }
  514. sc->result = DID_OK << 16; /* Set default reply as OK */
  515. pScsiReq = (SCSIIORequest_t *) mf;
  516. pScsiReply = (SCSIIOReply_t *) mr;
  517. if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
  518. dmfprintk((MYIOC_s_INFO_FMT
  519. "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
  520. ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
  521. }else{
  522. dmfprintk((MYIOC_s_INFO_FMT
  523. "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
  524. ioc->name, mf, mr, sc, req_idx));
  525. }
  526. if (pScsiReply == NULL) {
  527. /* special context reply handling */
  528. ;
  529. } else {
  530. u32 xfer_cnt;
  531. u16 status;
  532. u8 scsi_state, scsi_status;
  533. status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
  534. scsi_state = pScsiReply->SCSIState;
  535. scsi_status = pScsiReply->SCSIStatus;
  536. xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
  537. sc->resid = sc->request_bufflen - xfer_cnt;
  538. /*
  539. * if we get a data underrun indication, yet no data was
  540. * transferred and the SCSI status indicates that the
  541. * command was never started, change the data underrun
  542. * to success
  543. */
  544. if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
  545. (scsi_status == MPI_SCSI_STATUS_BUSY ||
  546. scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
  547. scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
  548. status = MPI_IOCSTATUS_SUCCESS;
  549. }
  550. dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
  551. "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
  552. "resid=%d bufflen=%d xfer_cnt=%d\n",
  553. ioc->id, sc->device->id, sc->device->lun,
  554. status, scsi_state, scsi_status, sc->resid,
  555. sc->request_bufflen, xfer_cnt));
  556. if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
  557. mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
  558. /*
  559. * Look for + dump FCP ResponseInfo[]!
  560. */
  561. if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
  562. pScsiReply->ResponseInfo) {
  563. printk(KERN_NOTICE "ha=%d id=%d lun=%d: "
  564. "FCP_ResponseInfo=%08xh\n",
  565. ioc->id, sc->device->id, sc->device->lun,
  566. le32_to_cpu(pScsiReply->ResponseInfo));
  567. }
  568. switch(status) {
  569. case MPI_IOCSTATUS_BUSY: /* 0x0002 */
  570. /* CHECKME!
  571. * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
  572. * But not: DID_BUS_BUSY lest one risk
  573. * killing interrupt handler:-(
  574. */
  575. sc->result = SAM_STAT_BUSY;
  576. break;
  577. case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
  578. case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
  579. sc->result = DID_BAD_TARGET << 16;
  580. break;
  581. case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
  582. /* Spoof to SCSI Selection Timeout! */
  583. sc->result = DID_NO_CONNECT << 16;
  584. if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
  585. hd->sel_timeout[pScsiReq->TargetID]++;
  586. break;
  587. case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
  588. case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
  589. case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
  590. /* Linux handles an unsolicited DID_RESET better
  591. * than an unsolicited DID_ABORT.
  592. */
  593. sc->result = DID_RESET << 16;
  594. /* GEM Workaround. */
  595. if (ioc->bus_type == SPI)
  596. mptscsih_no_negotiate(hd, sc);
  597. break;
  598. case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
  599. sc->resid = sc->request_bufflen - xfer_cnt;
  600. if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
  601. sc->result=DID_SOFT_ERROR << 16;
  602. else /* Sufficient data transfer occurred */
  603. sc->result = (DID_OK << 16) | scsi_status;
  604. dreplyprintk((KERN_NOTICE
  605. "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
  606. break;
  607. case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
  608. /*
  609. * Do upfront check for valid SenseData and give it
  610. * precedence!
  611. */
  612. sc->result = (DID_OK << 16) | scsi_status;
  613. if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
  614. /* Have already saved the status and sense data
  615. */
  616. ;
  617. } else {
  618. if (xfer_cnt < sc->underflow) {
  619. if (scsi_status == SAM_STAT_BUSY)
  620. sc->result = SAM_STAT_BUSY;
  621. else
  622. sc->result = DID_SOFT_ERROR << 16;
  623. }
  624. if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
  625. /* What to do?
  626. */
  627. sc->result = DID_SOFT_ERROR << 16;
  628. }
  629. else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
  630. /* Not real sure here either... */
  631. sc->result = DID_RESET << 16;
  632. }
  633. }
  634. dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
  635. sc->underflow));
  636. dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
  637. /* Report Queue Full
  638. */
  639. if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
  640. mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
  641. break;
  642. case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
  643. case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
  644. if (scsi_status == MPI_SCSI_STATUS_BUSY)
  645. sc->result = (DID_BUS_BUSY << 16) | scsi_status;
  646. else
  647. sc->result = (DID_OK << 16) | scsi_status;
  648. if (scsi_state == 0) {
  649. ;
  650. } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
  651. /*
  652. * If running against circa 200003dd 909 MPT f/w,
  653. * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
  654. * (QUEUE_FULL) returned from device! --> get 0x0000?128
  655. * and with SenseBytes set to 0.
  656. */
  657. if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
  658. mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
  659. }
  660. else if (scsi_state &
  661. (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
  662. ) {
  663. /*
  664. * What to do?
  665. */
  666. sc->result = DID_SOFT_ERROR << 16;
  667. }
  668. else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
  669. /* Not real sure here either... */
  670. sc->result = DID_RESET << 16;
  671. }
  672. else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
  673. /* Device Inq. data indicates that it supports
  674. * QTags, but rejects QTag messages.
  675. * This command completed OK.
  676. *
  677. * Not real sure here either so do nothing... */
  678. }
  679. if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
  680. mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
  681. /* Add handling of:
  682. * Reservation Conflict, Busy,
  683. * Command Terminated, CHECK
  684. */
  685. break;
  686. case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
  687. sc->result = DID_SOFT_ERROR << 16;
  688. break;
  689. case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
  690. case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
  691. case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
  692. case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
  693. case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
  694. case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
  695. case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
  696. case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
  697. case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
  698. case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
  699. default:
  700. /*
  701. * What to do?
  702. */
  703. sc->result = DID_SOFT_ERROR << 16;
  704. break;
  705. } /* switch(status) */
  706. dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result));
  707. } /* end of address reply case */
  708. /* Unmap the DMA buffers, if any. */
  709. if (sc->use_sg) {
  710. pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
  711. sc->use_sg, sc->sc_data_direction);
  712. } else if (sc->request_bufflen) {
  713. pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
  714. sc->request_bufflen, sc->sc_data_direction);
  715. }
  716. hd->ScsiLookup[req_idx] = NULL;
  717. sc->scsi_done(sc); /* Issue the command callback */
  718. /* Free Chain buffers */
  719. mptscsih_freeChainBuffers(ioc, req_idx);
  720. return 1;
  721. }
  722. /*
  723. * mptscsih_flush_running_cmds - For each command found, search
  724. * Scsi_Host instance taskQ and reply to OS.
  725. * Called only if recovering from a FW reload.
  726. * @hd: Pointer to a SCSI HOST structure
  727. *
  728. * Returns: None.
  729. *
  730. * Must be called while new I/Os are being queued.
  731. */
  732. static void
  733. mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
  734. {
  735. MPT_ADAPTER *ioc = hd->ioc;
  736. struct scsi_cmnd *SCpnt;
  737. MPT_FRAME_HDR *mf;
  738. int ii;
  739. int max = ioc->req_depth;
  740. dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
  741. for (ii= 0; ii < max; ii++) {
  742. if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
  743. /* Command found.
  744. */
  745. /* Null ScsiLookup index
  746. */
  747. hd->ScsiLookup[ii] = NULL;
  748. mf = MPT_INDEX_2_MFPTR(ioc, ii);
  749. dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
  750. mf, SCpnt));
  751. /* Set status, free OS resources (SG DMA buffers)
  752. * Do OS callback
  753. * Free driver resources (chain, msg buffers)
  754. */
  755. if (SCpnt->use_sg) {
  756. pci_unmap_sg(ioc->pcidev,
  757. (struct scatterlist *) SCpnt->request_buffer,
  758. SCpnt->use_sg,
  759. SCpnt->sc_data_direction);
  760. } else if (SCpnt->request_bufflen) {
  761. pci_unmap_single(ioc->pcidev,
  762. SCpnt->SCp.dma_handle,
  763. SCpnt->request_bufflen,
  764. SCpnt->sc_data_direction);
  765. }
  766. SCpnt->result = DID_RESET << 16;
  767. SCpnt->host_scribble = NULL;
  768. /* Free Chain buffers */
  769. mptscsih_freeChainBuffers(ioc, ii);
  770. /* Free Message frames */
  771. mpt_free_msg_frame(ioc, mf);
  772. SCpnt->scsi_done(SCpnt); /* Issue the command callback */
  773. }
  774. }
  775. return;
  776. }
  777. /*
  778. * mptscsih_search_running_cmds - Delete any commands associated
  779. * with the specified target and lun. Function called only
  780. * when a lun is disable by mid-layer.
  781. * Do NOT access the referenced scsi_cmnd structure or
  782. * members. Will cause either a paging or NULL ptr error.
  783. * (BUT, BUT, BUT, the code does reference it! - mdr)
  784. * @hd: Pointer to a SCSI HOST structure
  785. * @vdevice: per device private data
  786. *
  787. * Returns: None.
  788. *
  789. * Called from slave_destroy.
  790. */
  791. static void
  792. mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
  793. {
  794. SCSIIORequest_t *mf = NULL;
  795. int ii;
  796. int max = hd->ioc->req_depth;
  797. struct scsi_cmnd *sc;
  798. dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
  799. vdevice->target_id, vdevice->lun, max));
  800. for (ii=0; ii < max; ii++) {
  801. if ((sc = hd->ScsiLookup[ii]) != NULL) {
  802. mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
  803. dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
  804. hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
  805. if ((mf->TargetID != ((u8)vdevice->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
  806. continue;
  807. /* Cleanup
  808. */
  809. hd->ScsiLookup[ii] = NULL;
  810. mptscsih_freeChainBuffers(hd->ioc, ii);
  811. mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
  812. if (sc->use_sg) {
  813. pci_unmap_sg(hd->ioc->pcidev,
  814. (struct scatterlist *) sc->request_buffer,
  815. sc->use_sg,
  816. sc->sc_data_direction);
  817. } else if (sc->request_bufflen) {
  818. pci_unmap_single(hd->ioc->pcidev,
  819. sc->SCp.dma_handle,
  820. sc->request_bufflen,
  821. sc->sc_data_direction);
  822. }
  823. sc->host_scribble = NULL;
  824. sc->result = DID_NO_CONNECT << 16;
  825. sc->scsi_done(sc);
  826. }
  827. }
  828. return;
  829. }
  830. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  831. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  832. /*
  833. * mptscsih_report_queue_full - Report QUEUE_FULL status returned
  834. * from a SCSI target device.
  835. * @sc: Pointer to scsi_cmnd structure
  836. * @pScsiReply: Pointer to SCSIIOReply_t
  837. * @pScsiReq: Pointer to original SCSI request
  838. *
  839. * This routine periodically reports QUEUE_FULL status returned from a
  840. * SCSI target device. It reports this to the console via kernel
  841. * printk() API call, not more than once every 10 seconds.
  842. */
  843. static void
  844. mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
  845. {
  846. long time = jiffies;
  847. MPT_SCSI_HOST *hd;
  848. if (sc->device == NULL)
  849. return;
  850. if (sc->device->host == NULL)
  851. return;
  852. if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL)
  853. return;
  854. if (time - hd->last_queue_full > 10 * HZ) {
  855. dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
  856. hd->ioc->name, 0, sc->device->id, sc->device->lun));
  857. hd->last_queue_full = time;
  858. }
  859. }
  860. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  861. /*
  862. * mptscsih_remove - Removed scsi devices
  863. * @pdev: Pointer to pci_dev structure
  864. *
  865. *
  866. */
  867. void
  868. mptscsih_remove(struct pci_dev *pdev)
  869. {
  870. MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
  871. struct Scsi_Host *host = ioc->sh;
  872. MPT_SCSI_HOST *hd;
  873. #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
  874. int count;
  875. unsigned long flags;
  876. #endif
  877. int sz1;
  878. if(!host) {
  879. mpt_detach(pdev);
  880. return;
  881. }
  882. scsi_remove_host(host);
  883. if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL)
  884. return;
  885. #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
  886. /* Check DV thread active */
  887. count = 10 * HZ;
  888. spin_lock_irqsave(&dvtaskQ_lock, flags);
  889. if (dvtaskQ_active) {
  890. spin_unlock_irqrestore(&dvtaskQ_lock, flags);
  891. while(dvtaskQ_active && --count)
  892. schedule_timeout_interruptible(1);
  893. } else {
  894. spin_unlock_irqrestore(&dvtaskQ_lock, flags);
  895. }
  896. if (!count)
  897. printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");
  898. #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
  899. else
  900. printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);
  901. #endif
  902. #endif
  903. mptscsih_shutdown(pdev);
  904. sz1=0;
  905. if (hd->ScsiLookup != NULL) {
  906. sz1 = hd->ioc->req_depth * sizeof(void *);
  907. kfree(hd->ScsiLookup);
  908. hd->ScsiLookup = NULL;
  909. }
  910. /*
  911. * Free pointer array.
  912. */
  913. kfree(hd->Targets);
  914. hd->Targets = NULL;
  915. dprintk((MYIOC_s_INFO_FMT
  916. "Free'd ScsiLookup (%d) memory\n",
  917. hd->ioc->name, sz1));
  918. kfree(hd->info_kbuf);
  919. /* NULL the Scsi_Host pointer
  920. */
  921. hd->ioc->sh = NULL;
  922. scsi_host_put(host);
  923. mpt_detach(pdev);
  924. }
  925. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  926. /*
  927. * mptscsih_shutdown - reboot notifier
  928. *
  929. */
  930. void
  931. mptscsih_shutdown(struct pci_dev *pdev)
  932. {
  933. MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
  934. struct Scsi_Host *host = ioc->sh;
  935. MPT_SCSI_HOST *hd;
  936. if(!host)
  937. return;
  938. hd = (MPT_SCSI_HOST *)host->hostdata;
  939. }
  940. #ifdef CONFIG_PM
  941. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  942. /*
  943. * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
  944. *
  945. *
  946. */
  947. int
  948. mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
  949. {
  950. mptscsih_shutdown(pdev);
  951. return mpt_suspend(pdev,state);
  952. }
  953. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  954. /*
  955. * mptscsih_resume - Fusion MPT scsi driver resume routine.
  956. *
  957. *
  958. */
  959. int
  960. mptscsih_resume(struct pci_dev *pdev)
  961. {
  962. MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
  963. struct Scsi_Host *host = ioc->sh;
  964. MPT_SCSI_HOST *hd;
  965. mpt_resume(pdev);
  966. if(!host)
  967. return 0;
  968. hd = (MPT_SCSI_HOST *)host->hostdata;
  969. if(!hd)
  970. return 0;
  971. #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
  972. {
  973. unsigned long lflags;
  974. spin_lock_irqsave(&dvtaskQ_lock, lflags);
  975. if (!dvtaskQ_active) {
  976. dvtaskQ_active = 1;
  977. spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
  978. INIT_WORK(&dvTaskQ_task,
  979. mptscsih_domainValidation, (void *) hd);
  980. schedule_work(&dvTaskQ_task);
  981. } else {
  982. spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
  983. }
  984. }
  985. #endif
  986. return 0;
  987. }
  988. #endif
  989. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  990. /**
  991. * mptscsih_info - Return information about MPT adapter
  992. * @SChost: Pointer to Scsi_Host structure
  993. *
  994. * (linux scsi_host_template.info routine)
  995. *
  996. * Returns pointer to buffer where information was written.
  997. */
  998. const char *
  999. mptscsih_info(struct Scsi_Host *SChost)
  1000. {
  1001. MPT_SCSI_HOST *h;
  1002. int size = 0;
  1003. h = (MPT_SCSI_HOST *)SChost->hostdata;
  1004. if (h) {
  1005. if (h->info_kbuf == NULL)
  1006. if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
  1007. return h->info_kbuf;
  1008. h->info_kbuf[0] = '\0';
  1009. mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
  1010. h->info_kbuf[size-1] = '\0';
  1011. }
  1012. return h->info_kbuf;
  1013. }
  1014. struct info_str {
  1015. char *buffer;
  1016. int length;
  1017. int offset;
  1018. int pos;
  1019. };
  1020. static void
  1021. mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
  1022. {
  1023. if (info->pos + len > info->length)
  1024. len = info->length - info->pos;
  1025. if (info->pos + len < info->offset) {
  1026. info->pos += len;
  1027. return;
  1028. }
  1029. if (info->pos < info->offset) {
  1030. data += (info->offset - info->pos);
  1031. len -= (info->offset - info->pos);
  1032. }
  1033. if (len > 0) {
  1034. memcpy(info->buffer + info->pos, data, len);
  1035. info->pos += len;
  1036. }
  1037. }
  1038. static int
  1039. mptscsih_copy_info(struct info_str *info, char *fmt, ...)
  1040. {
  1041. va_list args;
  1042. char buf[81];
  1043. int len;
  1044. va_start(args, fmt);
  1045. len = vsprintf(buf, fmt, args);
  1046. va_end(args);
  1047. mptscsih_copy_mem_info(info, buf, len);
  1048. return len;
  1049. }
  1050. static int
  1051. mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
  1052. {
  1053. struct info_str info;
  1054. info.buffer = pbuf;
  1055. info.length = len;
  1056. info.offset = offset;
  1057. info.pos = 0;
  1058. mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
  1059. mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
  1060. mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
  1061. mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
  1062. return ((info.pos > info.offset) ? info.pos - info.offset : 0);
  1063. }
  1064. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1065. /**
  1066. * mptscsih_proc_info - Return information about MPT adapter
  1067. *
  1068. * (linux scsi_host_template.info routine)
  1069. *
  1070. * buffer: if write, user data; if read, buffer for user
  1071. * length: if write, return length;
  1072. * offset: if write, 0; if read, the current offset into the buffer from
  1073. * the previous read.
  1074. * hostno: scsi host number
  1075. * func: if write = 1; if read = 0
  1076. */
  1077. int
  1078. mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
  1079. int length, int func)
  1080. {
  1081. MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
  1082. MPT_ADAPTER *ioc = hd->ioc;
  1083. int size = 0;
  1084. if (func) {
  1085. /*
  1086. * write is not supported
  1087. */
  1088. } else {
  1089. if (start)
  1090. *start = buffer;
  1091. size = mptscsih_host_info(ioc, buffer, offset, length);
  1092. }
  1093. return size;
  1094. }
  1095. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1096. #define ADD_INDEX_LOG(req_ent) do { } while(0)
  1097. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1098. /**
  1099. * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
  1100. * @SCpnt: Pointer to scsi_cmnd structure
  1101. * @done: Pointer SCSI mid-layer IO completion function
  1102. *
  1103. * (linux scsi_host_template.queuecommand routine)
  1104. * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
  1105. * from a linux scsi_cmnd request and send it to the IOC.
  1106. *
  1107. * Returns 0. (rtn value discarded by linux scsi mid-layer)
  1108. */
  1109. int
  1110. mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
  1111. {
  1112. MPT_SCSI_HOST *hd;
  1113. MPT_FRAME_HDR *mf;
  1114. SCSIIORequest_t *pScsiReq;
  1115. VirtDevice *vdev = SCpnt->device->hostdata;
  1116. int lun;
  1117. u32 datalen;
  1118. u32 scsictl;
  1119. u32 scsidir;
  1120. u32 cmd_len;
  1121. int my_idx;
  1122. int ii;
  1123. hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
  1124. lun = SCpnt->device->lun;
  1125. SCpnt->scsi_done = done;
  1126. dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
  1127. (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
  1128. if (hd->resetPending) {
  1129. dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
  1130. (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
  1131. return SCSI_MLQUEUE_HOST_BUSY;
  1132. }
  1133. /*
  1134. * Put together a MPT SCSI request...
  1135. */
  1136. if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) {
  1137. dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
  1138. hd->ioc->name));
  1139. return SCSI_MLQUEUE_HOST_BUSY;
  1140. }
  1141. pScsiReq = (SCSIIORequest_t *) mf;
  1142. my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
  1143. ADD_INDEX_LOG(my_idx);
  1144. /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
  1145. * Seems we may receive a buffer (datalen>0) even when there
  1146. * will be no data transfer! GRRRRR...
  1147. */
  1148. if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
  1149. datalen = SCpnt->request_bufflen;
  1150. scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
  1151. } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
  1152. datalen = SCpnt->request_bufflen;
  1153. scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
  1154. } else {
  1155. datalen = 0;
  1156. scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
  1157. }
  1158. /* Default to untagged. Once a target structure has been allocated,
  1159. * use the Inquiry data to determine if device supports tagged.
  1160. */
  1161. if (vdev
  1162. && (vdev->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
  1163. && (SCpnt->device->tagged_supported)) {
  1164. scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
  1165. } else {
  1166. scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
  1167. }
  1168. /* Use the above information to set up the message frame
  1169. */
  1170. pScsiReq->TargetID = (u8) vdev->target_id;
  1171. pScsiReq->Bus = vdev->bus_id;
  1172. pScsiReq->ChainOffset = 0;
  1173. pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
  1174. pScsiReq->CDBLength = SCpnt->cmd_len;
  1175. pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
  1176. pScsiReq->Reserved = 0;
  1177. pScsiReq->MsgFlags = mpt_msg_flags();
  1178. pScsiReq->LUN[0] = 0;
  1179. pScsiReq->LUN[1] = lun;
  1180. pScsiReq->LUN[2] = 0;
  1181. pScsiReq->LUN[3] = 0;
  1182. pScsiReq->LUN[4] = 0;
  1183. pScsiReq->LUN[5] = 0;
  1184. pScsiReq->LUN[6] = 0;
  1185. pScsiReq->LUN[7] = 0;
  1186. pScsiReq->Control = cpu_to_le32(scsictl);
  1187. /*
  1188. * Write SCSI CDB into the message
  1189. */
  1190. cmd_len = SCpnt->cmd_len;
  1191. for (ii=0; ii < cmd_len; ii++)
  1192. pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
  1193. for (ii=cmd_len; ii < 16; ii++)
  1194. pScsiReq->CDB[ii] = 0;
  1195. /* DataLength */
  1196. pScsiReq->DataLength = cpu_to_le32(datalen);
  1197. /* SenseBuffer low address */
  1198. pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
  1199. + (my_idx * MPT_SENSE_BUFFER_ALLOC));
  1200. /* Now add the SG list
  1201. * Always have a SGE even if null length.
  1202. */
  1203. if (datalen == 0) {
  1204. /* Add a NULL SGE */
  1205. mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
  1206. (dma_addr_t) -1);
  1207. } else {
  1208. /* Add a 32 or 64 bit SGE */
  1209. if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
  1210. goto fail;
  1211. }
  1212. hd->ScsiLookup[my_idx] = SCpnt;
  1213. SCpnt->host_scribble = NULL;
  1214. #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
  1215. if (hd->ioc->bus_type == SPI) {
  1216. int dvStatus = hd->ioc->spi_data.dvStatus[vdev->target_id];
  1217. int issueCmd = 1;
  1218. if (dvStatus || hd->ioc->spi_data.forceDv) {
  1219. if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
  1220. (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
  1221. unsigned long lflags;
  1222. /* Schedule DV if necessary */
  1223. spin_lock_irqsave(&dvtaskQ_lock, lflags);
  1224. if (!dvtaskQ_active) {
  1225. dvtaskQ_active = 1;
  1226. spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
  1227. INIT_WORK(&dvTaskQ_task, mptscsih_domainValidation, (void *) hd);
  1228. schedule_work(&dvTaskQ_task);
  1229. } else {
  1230. spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
  1231. }
  1232. hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV;
  1233. }
  1234. /* Trying to do DV to this target, extend timeout.
  1235. * Wait to issue until flag is clear
  1236. */
  1237. if (dvStatus & MPT_SCSICFG_DV_PENDING) {
  1238. mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
  1239. issueCmd = 0;
  1240. }
  1241. /* Set the DV flags.
  1242. */
  1243. if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
  1244. mptscsih_set_dvflags(hd, SCpnt);
  1245. if (!issueCmd)
  1246. goto fail;
  1247. }
  1248. }
  1249. #endif
  1250. mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
  1251. dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
  1252. hd->ioc->name, SCpnt, mf, my_idx));
  1253. DBG_DUMP_REQUEST_FRAME(mf)
  1254. return 0;
  1255. fail:
  1256. hd->ScsiLookup[my_idx] = NULL;
  1257. mptscsih_freeChainBuffers(hd->ioc, my_idx);
  1258. mpt_free_msg_frame(hd->ioc, mf);
  1259. return SCSI_MLQUEUE_HOST_BUSY;
  1260. }
  1261. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1262. /*
  1263. * mptscsih_freeChainBuffers - Function to free chain buffers associated
  1264. * with a SCSI IO request
  1265. * @hd: Pointer to the MPT_SCSI_HOST instance
  1266. * @req_idx: Index of the SCSI IO request frame.
  1267. *
  1268. * Called if SG chain buffer allocation fails and mptscsih callbacks.
  1269. * No return.
  1270. */
  1271. static void
  1272. mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
  1273. {
  1274. MPT_FRAME_HDR *chain;
  1275. unsigned long flags;
  1276. int chain_idx;
  1277. int next;
  1278. /* Get the first chain index and reset
  1279. * tracker state.
  1280. */
  1281. chain_idx = ioc->ReqToChain[req_idx];
  1282. ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
  1283. while (chain_idx != MPT_HOST_NO_CHAIN) {
  1284. /* Save the next chain buffer index */
  1285. next = ioc->ChainToChain[chain_idx];
  1286. /* Free this chain buffer and reset
  1287. * tracker
  1288. */
  1289. ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
  1290. chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
  1291. + (chain_idx * ioc->req_sz));
  1292. spin_lock_irqsave(&ioc->FreeQlock, flags);
  1293. list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
  1294. spin_unlock_irqrestore(&ioc->FreeQlock, flags);
  1295. dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
  1296. ioc->name, chain_idx));
  1297. /* handle next */
  1298. chain_idx = next;
  1299. }
  1300. return;
  1301. }
  1302. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1303. /*
  1304. * Reset Handling
  1305. */
  1306. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1307. /*
  1308. * mptscsih_TMHandler - Generic handler for SCSI Task Management.
  1309. * Fall through to mpt_HardResetHandler if: not operational, too many
  1310. * failed TM requests or handshake failure.
  1311. *
  1312. * @ioc: Pointer to MPT_ADAPTER structure
  1313. * @type: Task Management type
  1314. * @target: Logical Target ID for reset (if appropriate)
  1315. * @lun: Logical Unit for reset (if appropriate)
  1316. * @ctx2abort: Context for the task to be aborted (if appropriate)
  1317. *
  1318. * Remark: Currently invoked from a non-interrupt thread (_bh).
  1319. *
  1320. * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
  1321. * will be active.
  1322. *
  1323. * Returns 0 for SUCCESS or -1 if FAILED.
  1324. */
  1325. static int
  1326. mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
  1327. {
  1328. MPT_ADAPTER *ioc;
  1329. int rc = -1;
  1330. int doTask = 1;
  1331. u32 ioc_raw_state;
  1332. unsigned long flags;
  1333. /* If FW is being reloaded currently, return success to
  1334. * the calling function.
  1335. */
  1336. if (hd == NULL)
  1337. return 0;
  1338. ioc = hd->ioc;
  1339. if (ioc == NULL) {
  1340. printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
  1341. return FAILED;
  1342. }
  1343. dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
  1344. // SJR - CHECKME - Can we avoid this here?
  1345. // (mpt_HardResetHandler has this check...)
  1346. spin_lock_irqsave(&ioc->diagLock, flags);
  1347. if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
  1348. spin_unlock_irqrestore(&ioc->diagLock, flags);
  1349. return FAILED;
  1350. }
  1351. spin_unlock_irqrestore(&ioc->diagLock, flags);
  1352. /* Wait a fixed amount of time for the TM pending flag to be cleared.
  1353. * If we time out and not bus reset, then we return a FAILED status to the caller.
  1354. * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
  1355. * successful. Otherwise, reload the FW.
  1356. */
  1357. if (mptscsih_tm_pending_wait(hd) == FAILED) {
  1358. if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
  1359. dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: "
  1360. "Timed out waiting for last TM (%d) to complete! \n",
  1361. hd->ioc->name, hd->tmPending));
  1362. return FAILED;
  1363. } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
  1364. dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
  1365. "Timed out waiting for last TM (%d) to complete! \n",
  1366. hd->ioc->name, hd->tmPending));
  1367. return FAILED;
  1368. } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
  1369. dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
  1370. "Timed out waiting for last TM (%d) to complete! \n",
  1371. hd->ioc->name, hd->tmPending));
  1372. if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
  1373. return FAILED;
  1374. doTask = 0;
  1375. }
  1376. } else {
  1377. spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
  1378. hd->tmPending |= (1 << type);
  1379. spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
  1380. }
  1381. /* Is operational?
  1382. */
  1383. ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
  1384. #ifdef MPT_DEBUG_RESET
  1385. if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
  1386. printk(MYIOC_s_WARN_FMT
  1387. "TM Handler: IOC Not operational(0x%x)!\n",
  1388. hd->ioc->name, ioc_raw_state);
  1389. }
  1390. #endif
  1391. if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
  1392. && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
  1393. /* Isse the Task Mgmt request.
  1394. */
  1395. if (hd->hard_resets < -1)
  1396. hd->hard_resets++;
  1397. rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
  1398. if (rc) {
  1399. printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
  1400. } else {
  1401. dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
  1402. }
  1403. }
  1404. /* Only fall through to the HRH if this is a bus reset
  1405. */
  1406. if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
  1407. ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
  1408. dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
  1409. hd->ioc->name));
  1410. rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
  1411. }
  1412. dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
  1413. return rc;
  1414. }
  1415. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1416. /*
  1417. * mptscsih_IssueTaskMgmt - Generic send Task Management function.
  1418. * @hd: Pointer to MPT_SCSI_HOST structure
  1419. * @type: Task Management type
  1420. * @target: Logical Target ID for reset (if appropriate)
  1421. * @lun: Logical Unit for reset (if appropriate)
  1422. * @ctx2abort: Context for the task to be aborted (if appropriate)
  1423. *
  1424. * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
  1425. * or a non-interrupt thread. In the former, must not call schedule().
  1426. *
  1427. * Not all fields are meaningfull for all task types.
  1428. *
  1429. * Returns 0 for SUCCESS, -999 for "no msg frames",
  1430. * else other non-zero value returned.
  1431. */
  1432. static int
  1433. mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
  1434. {
  1435. MPT_FRAME_HDR *mf;
  1436. SCSITaskMgmt_t *pScsiTm;
  1437. int ii;
  1438. int retval;
  1439. /* Return Fail to calling function if no message frames available.
  1440. */
  1441. if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) {
  1442. dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
  1443. hd->ioc->name));
  1444. return FAILED;
  1445. }
  1446. dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
  1447. hd->ioc->name, mf));
  1448. /* Format the Request
  1449. */
  1450. pScsiTm = (SCSITaskMgmt_t *) mf;
  1451. pScsiTm->TargetID = target;
  1452. pScsiTm->Bus = channel;
  1453. pScsiTm->ChainOffset = 0;
  1454. pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
  1455. pScsiTm->Reserved = 0;
  1456. pScsiTm->TaskType = type;
  1457. pScsiTm->Reserved1 = 0;
  1458. pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
  1459. ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
  1460. for (ii= 0; ii < 8; ii++) {
  1461. pScsiTm->LUN[ii] = 0;
  1462. }
  1463. pScsiTm->LUN[1] = lun;
  1464. for (ii=0; ii < 7; ii++)
  1465. pScsiTm->Reserved2[ii] = 0;
  1466. pScsiTm->TaskMsgContext = ctx2abort;
  1467. dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
  1468. hd->ioc->name, ctx2abort, type));
  1469. DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
  1470. if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
  1471. sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
  1472. CAN_SLEEP)) != 0) {
  1473. dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
  1474. " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
  1475. hd->ioc, mf));
  1476. mpt_free_msg_frame(hd->ioc, mf);
  1477. return retval;
  1478. }
  1479. if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
  1480. dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
  1481. " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
  1482. hd->ioc, mf));
  1483. mpt_free_msg_frame(hd->ioc, mf);
  1484. dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
  1485. hd->ioc->name));
  1486. retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
  1487. }
  1488. return retval;
  1489. }
  1490. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1491. /**
  1492. * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
  1493. * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
  1494. *
  1495. * (linux scsi_host_template.eh_abort_handler routine)
  1496. *
  1497. * Returns SUCCESS or FAILED.
  1498. */
  1499. int
  1500. mptscsih_abort(struct scsi_cmnd * SCpnt)
  1501. {
  1502. MPT_SCSI_HOST *hd;
  1503. MPT_ADAPTER *ioc;
  1504. MPT_FRAME_HDR *mf;
  1505. u32 ctx2abort;
  1506. int scpnt_idx;
  1507. int retval;
  1508. VirtDevice *vdev;
  1509. /* If we can't locate our host adapter structure, return FAILED status.
  1510. */
  1511. if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
  1512. SCpnt->result = DID_RESET << 16;
  1513. SCpnt->scsi_done(SCpnt);
  1514. dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: "
  1515. "Can't locate host! (sc=%p)\n",
  1516. SCpnt));
  1517. return FAILED;
  1518. }
  1519. ioc = hd->ioc;
  1520. if (hd->resetPending) {
  1521. return FAILED;
  1522. }
  1523. if (hd->timeouts < -1)
  1524. hd->timeouts++;
  1525. /* Find this command
  1526. */
  1527. if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
  1528. /* Cmd not found in ScsiLookup.
  1529. * Do OS callback.
  1530. */
  1531. SCpnt->result = DID_RESET << 16;
  1532. dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: "
  1533. "Command not in the active list! (sc=%p)\n",
  1534. hd->ioc->name, SCpnt));
  1535. return SUCCESS;
  1536. }
  1537. printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
  1538. hd->ioc->name, SCpnt);
  1539. scsi_print_command(SCpnt);
  1540. /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
  1541. * (the IO to be ABORT'd)
  1542. *
  1543. * NOTE: Since we do not byteswap MsgContext, we do not
  1544. * swap it here either. It is an opaque cookie to
  1545. * the controller, so it does not matter. -DaveM
  1546. */
  1547. mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
  1548. ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
  1549. hd->abortSCpnt = SCpnt;
  1550. vdev = SCpnt->device->hostdata;
  1551. retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
  1552. vdev->bus_id, vdev->target_id, vdev->lun,
  1553. ctx2abort, 2 /* 2 second timeout */);
  1554. printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
  1555. hd->ioc->name,
  1556. ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
  1557. if (retval == 0)
  1558. return SUCCESS;
  1559. if(retval != FAILED ) {
  1560. hd->tmPending = 0;
  1561. hd->tmState = TM_STATE_NONE;
  1562. }
  1563. return FAILED;
  1564. }
  1565. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1566. /**
  1567. * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
  1568. * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
  1569. *
  1570. * (linux scsi_host_template.eh_dev_reset_handler routine)
  1571. *
  1572. * Returns SUCCESS or FAILED.
  1573. */
  1574. int
  1575. mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
  1576. {
  1577. MPT_SCSI_HOST *hd;
  1578. int retval;
  1579. VirtDevice *vdev;
  1580. /* If we can't locate our host adapter structure, return FAILED status.
  1581. */
  1582. if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
  1583. dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: "
  1584. "Can't locate host! (sc=%p)\n",
  1585. SCpnt));
  1586. return FAILED;
  1587. }
  1588. if (hd->resetPending)
  1589. return FAILED;
  1590. printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n",
  1591. hd->ioc->name, SCpnt);
  1592. scsi_print_command(SCpnt);
  1593. vdev = SCpnt->device->hostdata;
  1594. retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
  1595. vdev->bus_id, vdev->target_id,
  1596. 0, 0, 5 /* 5 second timeout */);
  1597. printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
  1598. hd->ioc->name,
  1599. ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
  1600. if (retval == 0)
  1601. return SUCCESS;
  1602. if(retval != FAILED ) {
  1603. hd->tmPending = 0;
  1604. hd->tmState = TM_STATE_NONE;
  1605. }
  1606. return FAILED;
  1607. }
  1608. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1609. /**
  1610. * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
  1611. * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
  1612. *
  1613. * (linux scsi_host_template.eh_bus_reset_handler routine)
  1614. *
  1615. * Returns SUCCESS or FAILED.
  1616. */
  1617. int
  1618. mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
  1619. {
  1620. MPT_SCSI_HOST *hd;
  1621. int retval;
  1622. VirtDevice *vdev;
  1623. /* If we can't locate our host adapter structure, return FAILED status.
  1624. */
  1625. if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
  1626. dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: "
  1627. "Can't locate host! (sc=%p)\n",
  1628. SCpnt ) );
  1629. return FAILED;
  1630. }
  1631. printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n",
  1632. hd->ioc->name, SCpnt);
  1633. scsi_print_command(SCpnt);
  1634. if (hd->timeouts < -1)
  1635. hd->timeouts++;
  1636. vdev = SCpnt->device->hostdata;
  1637. retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
  1638. vdev->bus_id, 0, 0, 0, 5 /* 5 second timeout */);
  1639. printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
  1640. hd->ioc->name,
  1641. ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
  1642. if (retval == 0)
  1643. return SUCCESS;
  1644. if(retval != FAILED ) {
  1645. hd->tmPending = 0;
  1646. hd->tmState = TM_STATE_NONE;
  1647. }
  1648. return FAILED;
  1649. }
  1650. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1651. /**
  1652. * mptscsih_host_reset - Perform a SCSI host adapter RESET!
  1653. * new_eh variant
  1654. * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
  1655. *
  1656. * (linux scsi_host_template.eh_host_reset_handler routine)
  1657. *
  1658. * Returns SUCCESS or FAILED.
  1659. */
  1660. int
  1661. mptscsih_host_reset(struct scsi_cmnd *SCpnt)
  1662. {
  1663. MPT_SCSI_HOST * hd;
  1664. int status = SUCCESS;
  1665. /* If we can't locate the host to reset, then we failed. */
  1666. if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
  1667. dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
  1668. "Can't locate host! (sc=%p)\n",
  1669. SCpnt ) );
  1670. return FAILED;
  1671. }
  1672. printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n",
  1673. hd->ioc->name, SCpnt);
  1674. /* If our attempts to reset the host failed, then return a failed
  1675. * status. The host will be taken off line by the SCSI mid-layer.
  1676. */
  1677. if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
  1678. status = FAILED;
  1679. } else {
  1680. /* Make sure TM pending is cleared and TM state is set to
  1681. * NONE.
  1682. */
  1683. hd->tmPending = 0;
  1684. hd->tmState = TM_STATE_NONE;
  1685. }
  1686. dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: "
  1687. "Status = %s\n",
  1688. (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
  1689. return status;
  1690. }
  1691. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1692. /**
  1693. * mptscsih_tm_pending_wait - wait for pending task management request to
  1694. * complete.
  1695. * @hd: Pointer to MPT host structure.
  1696. *
  1697. * Returns {SUCCESS,FAILED}.
  1698. */
  1699. static int
  1700. mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
  1701. {
  1702. unsigned long flags;
  1703. int loop_count = 4 * 10; /* Wait 10 seconds */
  1704. int status = FAILED;
  1705. do {
  1706. spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
  1707. if (hd->tmState == TM_STATE_NONE) {
  1708. hd->tmState = TM_STATE_IN_PROGRESS;
  1709. hd->tmPending = 1;
  1710. spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
  1711. status = SUCCESS;
  1712. break;
  1713. }
  1714. spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
  1715. msleep(250);
  1716. } while (--loop_count);
  1717. return status;
  1718. }
  1719. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1720. /**
  1721. * mptscsih_tm_wait_for_completion - wait for completion of TM task
  1722. * @hd: Pointer to MPT host structure.
  1723. *
  1724. * Returns {SUCCESS,FAILED}.
  1725. */
  1726. static int
  1727. mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
  1728. {
  1729. unsigned long flags;
  1730. int loop_count = 4 * timeout;
  1731. int status = FAILED;
  1732. do {
  1733. spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
  1734. if(hd->tmPending == 0) {
  1735. status = SUCCESS;
  1736. spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
  1737. break;
  1738. }
  1739. spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
  1740. msleep_interruptible(250);
  1741. } while (--loop_count);
  1742. return status;
  1743. }
  1744. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1745. /**
  1746. * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
  1747. * @ioc: Pointer to MPT_ADAPTER structure
  1748. * @mf: Pointer to SCSI task mgmt request frame
  1749. * @mr: Pointer to SCSI task mgmt reply frame
  1750. *
  1751. * This routine is called from mptbase.c::mpt_interrupt() at the completion
  1752. * of any SCSI task management request.
  1753. * This routine is registered with the MPT (base) driver at driver
  1754. * load/init time via the mpt_register() API call.
  1755. *
  1756. * Returns 1 indicating alloc'd request frame ptr should be freed.
  1757. */
  1758. int
  1759. mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
  1760. {
  1761. SCSITaskMgmtReply_t *pScsiTmReply;
  1762. SCSITaskMgmt_t *pScsiTmReq;
  1763. MPT_SCSI_HOST *hd;
  1764. unsigned long flags;
  1765. u16 iocstatus;
  1766. u8 tmType;
  1767. dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
  1768. ioc->name, mf, mr));
  1769. if (ioc->sh) {
  1770. /* Depending on the thread, a timer is activated for
  1771. * the TM request. Delete this timer on completion of TM.
  1772. * Decrement count of outstanding TM requests.
  1773. */
  1774. hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
  1775. } else {
  1776. dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
  1777. ioc->name));
  1778. return 1;
  1779. }
  1780. if (mr == NULL) {
  1781. dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
  1782. ioc->name, mf));
  1783. return 1;
  1784. } else {
  1785. pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
  1786. pScsiTmReq = (SCSITaskMgmt_t*)mf;
  1787. /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
  1788. tmType = pScsiTmReq->TaskType;
  1789. dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
  1790. ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
  1791. DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
  1792. iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
  1793. dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
  1794. ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
  1795. /* Error? (anything non-zero?) */
  1796. if (iocstatus) {
  1797. /* clear flags and continue.
  1798. */
  1799. if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
  1800. hd->abortSCpnt = NULL;
  1801. /* If an internal command is present
  1802. * or the TM failed - reload the FW.
  1803. * FC FW may respond FAILED to an ABORT
  1804. */
  1805. if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
  1806. if ((hd->cmdPtr) ||
  1807. (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
  1808. if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
  1809. printk((KERN_WARNING
  1810. " Firmware Reload FAILED!!\n"));
  1811. }
  1812. }
  1813. }
  1814. } else {
  1815. dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
  1816. hd->abortSCpnt = NULL;
  1817. }
  1818. }
  1819. spin_lock_irqsave(&ioc->FreeQlock, flags);
  1820. hd->tmPending = 0;
  1821. spin_unlock_irqrestore(&ioc->FreeQlock, flags);
  1822. hd->tmState = TM_STATE_NONE;
  1823. return 1;
  1824. }
  1825. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1826. /*
  1827. * This is anyones guess quite frankly.
  1828. */
  1829. int
  1830. mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
  1831. sector_t capacity, int geom[])
  1832. {
  1833. int heads;
  1834. int sectors;
  1835. sector_t cylinders;
  1836. ulong dummy;
  1837. heads = 64;
  1838. sectors = 32;
  1839. dummy = heads * sectors;
  1840. cylinders = capacity;
  1841. sector_div(cylinders,dummy);
  1842. /*
  1843. * Handle extended translation size for logical drives
  1844. * > 1Gb
  1845. */
  1846. if ((ulong)capacity >= 0x200000) {
  1847. heads = 255;
  1848. sectors = 63;
  1849. dummy = heads * sectors;
  1850. cylinders = capacity;
  1851. sector_div(cylinders,dummy);
  1852. }
  1853. /* return result */
  1854. geom[0] = heads;
  1855. geom[1] = sectors;
  1856. geom[2] = cylinders;
  1857. dprintk((KERN_NOTICE
  1858. ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
  1859. sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
  1860. return 0;
  1861. }
  1862. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1863. /*
  1864. * OS entry point to allow host driver to alloc memory
  1865. * for each scsi target. Called once per device the bus scan.
  1866. * Return non-zero if allocation fails.
  1867. */
  1868. int
  1869. mptscsih_target_alloc(struct scsi_target *starget)
  1870. {
  1871. VirtTarget *vtarget;
  1872. vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
  1873. if (!vtarget)
  1874. return -ENOMEM;
  1875. starget->hostdata = vtarget;
  1876. return 0;
  1877. }
  1878. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1879. /*
  1880. * OS entry point to allow host driver to alloc memory
  1881. * for each scsi device. Called once per device the bus scan.
  1882. * Return non-zero if allocation fails.
  1883. */
  1884. int
  1885. mptscsih_slave_alloc(struct scsi_device *sdev)
  1886. {
  1887. struct Scsi_Host *host = sdev->host;
  1888. MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
  1889. VirtTarget *vtarget;
  1890. VirtDevice *vdev;
  1891. struct scsi_target *starget;
  1892. vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
  1893. if (!vdev) {
  1894. printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
  1895. hd->ioc->name, sizeof(VirtDevice));
  1896. return -ENOMEM;
  1897. }
  1898. vdev->ioc_id = hd->ioc->id;
  1899. vdev->target_id = sdev->id;
  1900. vdev->bus_id = sdev->channel;
  1901. vdev->lun = sdev->lun;
  1902. sdev->hostdata = vdev;
  1903. starget = scsi_target(sdev);
  1904. vtarget = starget->hostdata;
  1905. vdev->vtarget = vtarget;
  1906. if (vtarget->num_luns == 0) {
  1907. hd->Targets[sdev->id] = vtarget;
  1908. vtarget->ioc_id = hd->ioc->id;
  1909. vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
  1910. vtarget->target_id = sdev->id;
  1911. vtarget->bus_id = sdev->channel;
  1912. if (hd->ioc->bus_type == SPI) {
  1913. if (hd->ioc->raid_data.isRaid & (1 << sdev->id)) {
  1914. vtarget->raidVolume = 1;
  1915. ddvtprintk((KERN_INFO
  1916. "RAID Volume @ id %d\n", sdev->id));
  1917. }
  1918. } else {
  1919. vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
  1920. }
  1921. }
  1922. vtarget->num_luns++;
  1923. return 0;
  1924. }
  1925. /*
  1926. * OS entry point to allow for host driver to free allocated memory
  1927. * Called if no device present or device being unloaded
  1928. */
  1929. void
  1930. mptscsih_target_destroy(struct scsi_target *starget)
  1931. {
  1932. if (starget->hostdata)
  1933. kfree(starget->hostdata);
  1934. starget->hostdata = NULL;
  1935. }
  1936. /*
  1937. * OS entry point to allow for host driver to free allocated memory
  1938. * Called if no device present or device being unloaded
  1939. */
  1940. void
  1941. mptscsih_slave_destroy(struct scsi_device *sdev)
  1942. {
  1943. struct Scsi_Host *host = sdev->host;
  1944. MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
  1945. VirtTarget *vtarget;
  1946. VirtDevice *vdevice;
  1947. struct scsi_target *starget;
  1948. starget = scsi_target(sdev);
  1949. vtarget = starget->hostdata;
  1950. vdevice = sdev->hostdata;
  1951. mptscsih_search_running_cmds(hd, vdevice);
  1952. vtarget->luns[0] &= ~(1 << vdevice->lun);
  1953. vtarget->num_luns--;
  1954. if (vtarget->num_luns == 0) {
  1955. mptscsih_negotiate_to_asyn_narrow(hd, vtarget);
  1956. if (hd->ioc->bus_type == SPI) {
  1957. if (mptscsih_is_phys_disk(hd->ioc, vtarget->target_id)) {
  1958. hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
  1959. } else {
  1960. hd->ioc->spi_data.dvStatus[vtarget->target_id] =
  1961. MPT_SCSICFG_NEGOTIATE;
  1962. if (!hd->negoNvram) {
  1963. hd->ioc->spi_data.dvStatus[vtarget->target_id] |=
  1964. MPT_SCSICFG_DV_NOT_DONE;
  1965. }
  1966. }
  1967. }
  1968. hd->Targets[sdev->id] = NULL;
  1969. }
  1970. mptscsih_synchronize_cache(hd, vdevice);
  1971. kfree(vdevice);
  1972. sdev->hostdata = NULL;
  1973. }
  1974. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  1975. /*
  1976. * mptscsih_change_queue_depth - This function will set a devices queue depth
  1977. * @sdev: per scsi_device pointer
  1978. * @qdepth: requested queue depth
  1979. *
  1980. * Adding support for new 'change_queue_depth' api.
  1981. */
  1982. int
  1983. mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
  1984. {
  1985. MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
  1986. VirtTarget *vtarget;
  1987. struct scsi_target *starget;
  1988. int max_depth;
  1989. int tagged;
  1990. starget = scsi_target(sdev);
  1991. vtarget = starget->hostdata;
  1992. if (hd->ioc->bus_type == SPI) {
  1993. if (vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
  1994. if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
  1995. max_depth = 1;
  1996. else if (((vtarget->inq_data[0] & 0x1f) == 0x00) &&
  1997. (vtarget->minSyncFactor <= MPT_ULTRA160 ))
  1998. max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
  1999. else
  2000. max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
  2001. } else {
  2002. /* error case - No Inq. Data */
  2003. max_depth = 1;
  2004. }
  2005. } else
  2006. max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
  2007. if (qdepth > max_depth)
  2008. qdepth = max_depth;
  2009. if (qdepth == 1)
  2010. tagged = 0;
  2011. else
  2012. tagged = MSG_SIMPLE_TAG;
  2013. scsi_adjust_queue_depth(sdev, tagged, qdepth);
  2014. return sdev->queue_depth;
  2015. }
  2016. /*
  2017. * OS entry point to adjust the queue_depths on a per-device basis.
  2018. * Called once per device the bus scan. Use it to force the queue_depth
  2019. * member to 1 if a device does not support Q tags.
  2020. * Return non-zero if fails.
  2021. */
  2022. int
  2023. mptscsih_slave_configure(struct scsi_device *sdev)
  2024. {
  2025. struct Scsi_Host *sh = sdev->host;
  2026. VirtTarget *vtarget;
  2027. VirtDevice *vdevice;
  2028. struct scsi_target *starget;
  2029. MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
  2030. int indexed_lun, lun_index;
  2031. starget = scsi_target(sdev);
  2032. vtarget = starget->hostdata;
  2033. vdevice = sdev->hostdata;
  2034. dsprintk((MYIOC_s_INFO_FMT
  2035. "device @ %p, id=%d, LUN=%d, channel=%d\n",
  2036. hd->ioc->name, sdev, sdev->id, sdev->lun, sdev->channel));
  2037. if (hd->ioc->bus_type == SPI)
  2038. dsprintk((MYIOC_s_INFO_FMT
  2039. "sdtr %d wdtr %d ppr %d inq length=%d\n",
  2040. hd->ioc->name, sdev->sdtr, sdev->wdtr,
  2041. sdev->ppr, sdev->inquiry_len));
  2042. if (sdev->id > sh->max_id) {
  2043. /* error case, should never happen */
  2044. scsi_adjust_queue_depth(sdev, 0, 1);
  2045. goto slave_configure_exit;
  2046. }
  2047. vdevice->configured_lun=1;
  2048. lun_index = (vdevice->lun >> 5); /* 32 luns per lun_index */
  2049. indexed_lun = (vdevice->lun % 32);
  2050. vtarget->luns[lun_index] |= (1 << indexed_lun);
  2051. mptscsih_initTarget(hd, vtarget, sdev->lun, sdev->inquiry,
  2052. sdev->inquiry_len );
  2053. mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
  2054. dsprintk((MYIOC_s_INFO_FMT
  2055. "Queue depth=%d, tflags=%x\n",
  2056. hd->ioc->name, sdev->queue_depth, vtarget->tflags));
  2057. if (hd->ioc->bus_type == SPI)
  2058. dsprintk((MYIOC_s_INFO_FMT
  2059. "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
  2060. hd->ioc->name, vtarget->negoFlags, vtarget->maxOffset,
  2061. vtarget->minSyncFactor));
  2062. slave_configure_exit:
  2063. dsprintk((MYIOC_s_INFO_FMT
  2064. "tagged %d, simple %d, ordered %d\n",
  2065. hd->ioc->name,sdev->tagged_supported, sdev->simple_tags,
  2066. sdev->ordered_tags));
  2067. return 0;
  2068. }
  2069. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2070. /*
  2071. * Private routines...
  2072. */
  2073. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2074. /* Utility function to copy sense data from the scsi_cmnd buffer
  2075. * to the FC and SCSI target structures.
  2076. *
  2077. */
  2078. static void
  2079. mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
  2080. {
  2081. VirtDevice *vdev;
  2082. SCSIIORequest_t *pReq;
  2083. u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
  2084. /* Get target structure
  2085. */
  2086. pReq = (SCSIIORequest_t *) mf;
  2087. vdev = sc->device->hostdata;
  2088. if (sense_count) {
  2089. u8 *sense_data;
  2090. int req_index;
  2091. /* Copy the sense received into the scsi command block. */
  2092. req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
  2093. sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
  2094. memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
  2095. /* Log SMART data (asc = 0x5D, non-IM case only) if required.
  2096. */
  2097. if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
  2098. if ((sense_data[12] == 0x5D) && (vdev->vtarget->raidVolume == 0)) {
  2099. int idx;
  2100. MPT_ADAPTER *ioc = hd->ioc;
  2101. idx = ioc->eventContext % ioc->eventLogSize;
  2102. ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
  2103. ioc->events[idx].eventContext = ioc->eventContext;
  2104. ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
  2105. (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
  2106. (sc->device->channel << 8) || sc->device->id;
  2107. ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
  2108. ioc->eventContext++;
  2109. }
  2110. }
  2111. } else {
  2112. dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
  2113. hd->ioc->name));
  2114. }
  2115. }
  2116. static u32
  2117. SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
  2118. {
  2119. MPT_SCSI_HOST *hd;
  2120. int i;
  2121. hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
  2122. for (i = 0; i < hd->ioc->req_depth; i++) {
  2123. if (hd->ScsiLookup[i] == sc) {
  2124. return i;
  2125. }
  2126. }
  2127. return -1;
  2128. }
  2129. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2130. int
  2131. mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
  2132. {
  2133. MPT_SCSI_HOST *hd;
  2134. unsigned long flags;
  2135. int ii;
  2136. dtmprintk((KERN_WARNING MYNAM
  2137. ": IOC %s_reset routed to SCSI host driver!\n",
  2138. reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
  2139. reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
  2140. /* If a FW reload request arrives after base installed but
  2141. * before all scsi hosts have been attached, then an alt_ioc
  2142. * may have a NULL sh pointer.
  2143. */
  2144. if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
  2145. return 0;
  2146. else
  2147. hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
  2148. if (reset_phase == MPT_IOC_SETUP_RESET) {
  2149. dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
  2150. /* Clean Up:
  2151. * 1. Set Hard Reset Pending Flag
  2152. * All new commands go to doneQ
  2153. */
  2154. hd->resetPending = 1;
  2155. } else if (reset_phase == MPT_IOC_PRE_RESET) {
  2156. dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
  2157. /* 2. Flush running commands
  2158. * Clean ScsiLookup (and associated memory)
  2159. * AND clean mytaskQ
  2160. */
  2161. /* 2b. Reply to OS all known outstanding I/O commands.
  2162. */
  2163. mptscsih_flush_running_cmds(hd);
  2164. /* 2c. If there was an internal command that
  2165. * has not completed, configuration or io request,
  2166. * free these resources.
  2167. */
  2168. if (hd->cmdPtr) {
  2169. del_timer(&hd->timer);
  2170. mpt_free_msg_frame(ioc, hd->cmdPtr);
  2171. }
  2172. dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
  2173. } else {
  2174. dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
  2175. /* Once a FW reload begins, all new OS commands are
  2176. * redirected to the doneQ w/ a reset status.
  2177. * Init all control structures.
  2178. */
  2179. /* ScsiLookup initialization
  2180. */
  2181. for (ii=0; ii < hd->ioc->req_depth; ii++)
  2182. hd->ScsiLookup[ii] = NULL;
  2183. /* 2. Chain Buffer initialization
  2184. */
  2185. /* 4. Renegotiate to all devices, if SPI
  2186. */
  2187. if (ioc->bus_type == SPI) {
  2188. dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
  2189. mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
  2190. }
  2191. /* 5. Enable new commands to be posted
  2192. */
  2193. spin_lock_irqsave(&ioc->FreeQlock, flags);
  2194. hd->tmPending = 0;
  2195. spin_unlock_irqrestore(&ioc->FreeQlock, flags);
  2196. hd->resetPending = 0;
  2197. hd->tmState = TM_STATE_NONE;
  2198. /* 6. If there was an internal command,
  2199. * wake this process up.
  2200. */
  2201. if (hd->cmdPtr) {
  2202. /*
  2203. * Wake up the original calling thread
  2204. */
  2205. hd->pLocal = &hd->localReply;
  2206. hd->pLocal->completion = MPT_SCANDV_DID_RESET;
  2207. hd->scandv_wait_done = 1;
  2208. wake_up(&hd->scandv_waitq);
  2209. hd->cmdPtr = NULL;
  2210. }
  2211. /* 7. SPI: Set flag to force DV and re-read IOC Page 3
  2212. */
  2213. if (ioc->bus_type == SPI) {
  2214. ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
  2215. ddvtprintk(("Set reload IOC Pg3 Flag\n"));
  2216. }
  2217. /* 7. FC: Rescan for blocked rports which might have returned.
  2218. */
  2219. else if (ioc->bus_type == FC) {
  2220. int work_count;
  2221. unsigned long flags;
  2222. spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
  2223. work_count = ++ioc->fc_rescan_work_count;
  2224. spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
  2225. if (work_count == 1)
  2226. schedule_work(&ioc->fc_rescan_work);
  2227. }
  2228. dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
  2229. }
  2230. return 1; /* currently means nothing really */
  2231. }
  2232. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2233. /* work queue thread to clear the persitency table */
  2234. static void
  2235. mptscsih_sas_persist_clear_table(void * arg)
  2236. {
  2237. MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
  2238. mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
  2239. }
  2240. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2241. int
  2242. mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
  2243. {
  2244. MPT_SCSI_HOST *hd;
  2245. u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
  2246. int work_count;
  2247. unsigned long flags;
  2248. devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
  2249. ioc->name, event));
  2250. if (ioc->sh == NULL ||
  2251. ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL))
  2252. return 1;
  2253. switch (event) {
  2254. case MPI_EVENT_UNIT_ATTENTION: /* 03 */
  2255. /* FIXME! */
  2256. break;
  2257. case MPI_EVENT_IOC_BUS_RESET: /* 04 */
  2258. case MPI_EVENT_EXT_BUS_RESET: /* 05 */
  2259. if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
  2260. hd->soft_resets++;
  2261. break;
  2262. case MPI_EVENT_LOGOUT: /* 09 */
  2263. /* FIXME! */
  2264. break;
  2265. case MPI_EVENT_RESCAN: /* 06 */
  2266. spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
  2267. work_count = ++ioc->fc_rescan_work_count;
  2268. spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
  2269. if (work_count == 1)
  2270. schedule_work(&ioc->fc_rescan_work);
  2271. break;
  2272. /*
  2273. * CHECKME! Don't think we need to do
  2274. * anything for these, but...
  2275. */
  2276. case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
  2277. case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
  2278. /*
  2279. * CHECKME! Falling thru...
  2280. */
  2281. break;
  2282. case MPI_EVENT_INTEGRATED_RAID: /* 0B */
  2283. {
  2284. #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
  2285. pMpiEventDataRaid_t pRaidEventData =
  2286. (pMpiEventDataRaid_t) pEvReply->Data;
  2287. /* Domain Validation Needed */
  2288. if (ioc->bus_type == SPI &&
  2289. pRaidEventData->ReasonCode ==
  2290. MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED)
  2291. mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum);
  2292. #endif
  2293. break;
  2294. }
  2295. /* Persistent table is full. */
  2296. case MPI_EVENT_PERSISTENT_TABLE_FULL:
  2297. INIT_WORK(&mptscsih_persistTask,
  2298. mptscsih_sas_persist_clear_table,(void *)ioc);
  2299. schedule_work(&mptscsih_persistTask);
  2300. break;
  2301. case MPI_EVENT_NONE: /* 00 */
  2302. case MPI_EVENT_LOG_DATA: /* 01 */
  2303. case MPI_EVENT_STATE_CHANGE: /* 02 */
  2304. case MPI_EVENT_EVENT_CHANGE: /* 0A */
  2305. default:
  2306. dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
  2307. break;
  2308. }
  2309. return 1; /* currently means nothing really */
  2310. }
  2311. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2312. /*
  2313. * mptscsih_initTarget - Target, LUN alloc/free functionality.
  2314. * @hd: Pointer to MPT_SCSI_HOST structure
  2315. * @vtarget: per target private data
  2316. * @lun: SCSI LUN id
  2317. * @data: Pointer to data
  2318. * @dlen: Number of INQUIRY bytes
  2319. *
  2320. * NOTE: It's only SAFE to call this routine if data points to
  2321. * sane & valid STANDARD INQUIRY data!
  2322. *
  2323. * Allocate and initialize memory for this target.
  2324. * Save inquiry data.
  2325. *
  2326. */
  2327. static void
  2328. mptscsih_initTarget(MPT_SCSI_HOST *hd, VirtTarget *vtarget, u8 lun, char *data, int dlen)
  2329. {
  2330. SpiCfgData *pSpi;
  2331. char data_56;
  2332. int inq_len;
  2333. dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
  2334. hd->ioc->name, vtarget->bus_id, vtarget->target_id, lun, hd));
  2335. /*
  2336. * If the peripheral qualifier filter is enabled then if the target reports a 0x1
  2337. * (i.e. The targer is capable of supporting the specified peripheral device type
  2338. * on this logical unit; however, the physical device is not currently connected
  2339. * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
  2340. * capable of supporting a physical device on this logical unit). This is to work
  2341. * around a bug in th emid-layer in some distributions in which the mid-layer will
  2342. * continue to try to communicate to the LUN and evntually create a dummy LUN.
  2343. */
  2344. if (hd->mpt_pq_filter && dlen && (data[0] & 0xE0))
  2345. data[0] |= 0x40;
  2346. /* Is LUN supported? If so, upper 2 bits will be 0
  2347. * in first byte of inquiry data.
  2348. */
  2349. if (data[0] & 0xe0)
  2350. return;
  2351. if (vtarget == NULL)
  2352. return;
  2353. if (data)
  2354. vtarget->type = data[0];
  2355. if (hd->ioc->bus_type != SPI)
  2356. return;
  2357. if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
  2358. /* Treat all Processors as SAF-TE if
  2359. * command line option is set */
  2360. vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
  2361. mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
  2362. }else if ((data[0] == TYPE_PROCESSOR) &&
  2363. !(vtarget->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
  2364. if ( dlen > 49 ) {
  2365. vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
  2366. if ( data[44] == 'S' &&
  2367. data[45] == 'A' &&
  2368. data[46] == 'F' &&
  2369. data[47] == '-' &&
  2370. data[48] == 'T' &&
  2371. data[49] == 'E' ) {
  2372. vtarget->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
  2373. mptscsih_writeIOCPage4(hd, vtarget->target_id, vtarget->bus_id);
  2374. }
  2375. }
  2376. }
  2377. if (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
  2378. inq_len = dlen < 8 ? dlen : 8;
  2379. memcpy (vtarget->inq_data, data, inq_len);
  2380. /* If have not done DV, set the DV flag.
  2381. */
  2382. pSpi = &hd->ioc->spi_data;
  2383. if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
  2384. if (pSpi->dvStatus[vtarget->target_id] & MPT_SCSICFG_DV_NOT_DONE)
  2385. pSpi->dvStatus[vtarget->target_id] |= MPT_SCSICFG_NEED_DV;
  2386. }
  2387. vtarget->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
  2388. data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
  2389. if (dlen > 56) {
  2390. if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
  2391. /* Update the target capabilities
  2392. */
  2393. data_56 = data[56];
  2394. vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
  2395. }
  2396. }
  2397. mptscsih_setTargetNegoParms(hd, vtarget, data_56);
  2398. } else {
  2399. /* Initial Inquiry may not request enough data bytes to
  2400. * obtain byte 57. DV will; if target doesn't return
  2401. * at least 57 bytes, data[56] will be zero. */
  2402. if (dlen > 56) {
  2403. if ( (!(vtarget->tflags & MPT_TARGET_FLAGS_VALID_56))) {
  2404. /* Update the target capabilities
  2405. */
  2406. data_56 = data[56];
  2407. vtarget->tflags |= MPT_TARGET_FLAGS_VALID_56;
  2408. mptscsih_setTargetNegoParms(hd, vtarget, data_56);
  2409. }
  2410. }
  2411. }
  2412. }
  2413. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2414. /*
  2415. * Update the target negotiation parameters based on the
  2416. * the Inquiry data, adapter capabilities, and NVRAM settings.
  2417. *
  2418. */
  2419. static void
  2420. mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target, char byte56)
  2421. {
  2422. SpiCfgData *pspi_data = &hd->ioc->spi_data;
  2423. int id = (int) target->target_id;
  2424. int nvram;
  2425. VirtTarget *vtarget;
  2426. int ii;
  2427. u8 width = MPT_NARROW;
  2428. u8 factor = MPT_ASYNC;
  2429. u8 offset = 0;
  2430. u8 version, nfactor;
  2431. u8 noQas = 1;
  2432. target->negoFlags = pspi_data->noQas;
  2433. /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
  2434. * support. If available, default QAS to off and allow enabling.
  2435. * If not available, default QAS to on, turn off for non-disks.
  2436. */
  2437. /* Set flags based on Inquiry data
  2438. */
  2439. version = target->inq_data[2] & 0x07;
  2440. if (version < 2) {
  2441. width = 0;
  2442. factor = MPT_ULTRA2;
  2443. offset = pspi_data->maxSyncOffset;
  2444. target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
  2445. } else {
  2446. if (target->inq_data[7] & 0x20) {
  2447. width = 1;
  2448. }
  2449. if (target->inq_data[7] & 0x10) {
  2450. factor = pspi_data->minSyncFactor;
  2451. if (target->tflags & MPT_TARGET_FLAGS_VALID_56) {
  2452. /* bits 2 & 3 show Clocking support */
  2453. if ((byte56 & 0x0C) == 0)
  2454. factor = MPT_ULTRA2;
  2455. else {
  2456. if ((byte56 & 0x03) == 0)
  2457. factor = MPT_ULTRA160;
  2458. else {
  2459. factor = MPT_ULTRA320;
  2460. if (byte56 & 0x02)
  2461. {
  2462. ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
  2463. noQas = 0;
  2464. }
  2465. if (target->inq_data[0] == TYPE_TAPE) {
  2466. if (byte56 & 0x01)
  2467. target->negoFlags |= MPT_TAPE_NEGO_IDP;
  2468. }
  2469. }
  2470. }
  2471. } else {
  2472. ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
  2473. noQas = 0;
  2474. }
  2475. offset = pspi_data->maxSyncOffset;
  2476. /* If RAID, never disable QAS
  2477. * else if non RAID, do not disable
  2478. * QAS if bit 1 is set
  2479. * bit 1 QAS support, non-raid only
  2480. * bit 0 IU support
  2481. */
  2482. if (target->raidVolume == 1) {
  2483. noQas = 0;
  2484. }
  2485. } else {
  2486. factor = MPT_ASYNC;
  2487. offset = 0;
  2488. }
  2489. }
  2490. if ( (target->inq_data[7] & 0x02) == 0) {
  2491. target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
  2492. }
  2493. /* Update tflags based on NVRAM settings. (SCSI only)
  2494. */
  2495. if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
  2496. nvram = pspi_data->nvram[id];
  2497. nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
  2498. if (width)
  2499. width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
  2500. if (offset > 0) {
  2501. /* Ensure factor is set to the
  2502. * maximum of: adapter, nvram, inquiry
  2503. */
  2504. if (nfactor) {
  2505. if (nfactor < pspi_data->minSyncFactor )
  2506. nfactor = pspi_data->minSyncFactor;
  2507. factor = max(factor, nfactor);
  2508. if (factor == MPT_ASYNC)
  2509. offset = 0;
  2510. } else {
  2511. offset = 0;
  2512. factor = MPT_ASYNC;
  2513. }
  2514. } else {
  2515. factor = MPT_ASYNC;
  2516. }
  2517. }
  2518. /* Make sure data is consistent
  2519. */
  2520. if ((!width) && (factor < MPT_ULTRA2)) {
  2521. factor = MPT_ULTRA2;
  2522. }
  2523. /* Save the data to the target structure.
  2524. */
  2525. target->minSyncFactor = factor;
  2526. target->maxOffset = offset;
  2527. target->maxWidth = width;
  2528. target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
  2529. /* Disable unused features.
  2530. */
  2531. if (!width)
  2532. target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
  2533. if (!offset)
  2534. target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
  2535. if ( factor > MPT_ULTRA320 )
  2536. noQas = 0;
  2537. /* GEM, processor WORKAROUND
  2538. */
  2539. if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) {
  2540. target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
  2541. pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
  2542. } else {
  2543. if (noQas && (pspi_data->noQas == 0)) {
  2544. pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
  2545. target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
  2546. /* Disable QAS in a mixed configuration case
  2547. */
  2548. ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
  2549. for (ii = 0; ii < id; ii++) {
  2550. if ( (vtarget = hd->Targets[ii]) ) {
  2551. vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
  2552. mptscsih_writeSDP1(hd, 0, ii, vtarget->negoFlags);
  2553. }
  2554. }
  2555. }
  2556. }
  2557. /* Write SDP1 on this I/O to this target */
  2558. if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
  2559. ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
  2560. mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
  2561. pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
  2562. } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
  2563. ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
  2564. mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
  2565. pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
  2566. }
  2567. }
  2568. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2569. /*
  2570. * If no Target, bus reset on 1st I/O. Set the flag to
  2571. * prevent any future negotiations to this device.
  2572. */
  2573. static void
  2574. mptscsih_no_negotiate(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
  2575. {
  2576. VirtDevice *vdev;
  2577. if ((vdev = sc->device->hostdata) != NULL)
  2578. hd->ioc->spi_data.dvStatus[vdev->target_id] |= MPT_SCSICFG_BLK_NEGO;
  2579. return;
  2580. }
  2581. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2582. /*
  2583. * SCSI Config Page functionality ...
  2584. */
  2585. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2586. /* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags
  2587. * based on width, factor and offset parameters.
  2588. * @width: bus width
  2589. * @factor: sync factor
  2590. * @offset: sync offset
  2591. * @requestedPtr: pointer to requested values (updated)
  2592. * @configurationPtr: pointer to configuration values (updated)
  2593. * @flags: flags to block WDTR or SDTR negotiation
  2594. *
  2595. * Return: None.
  2596. *
  2597. * Remark: Called by writeSDP1 and _dv_params
  2598. */
  2599. static void
  2600. mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
  2601. {
  2602. u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
  2603. u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
  2604. *configurationPtr = 0;
  2605. *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
  2606. *requestedPtr |= (offset << 16) | (factor << 8);
  2607. if (width && offset && !nowide && !nosync) {
  2608. if (factor < MPT_ULTRA160) {
  2609. *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
  2610. if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
  2611. *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
  2612. if (flags & MPT_TAPE_NEGO_IDP)
  2613. *requestedPtr |= 0x08000000;
  2614. } else if (factor < MPT_ULTRA2) {
  2615. *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
  2616. }
  2617. }
  2618. if (nowide)
  2619. *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
  2620. if (nosync)
  2621. *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
  2622. return;
  2623. }
  2624. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2625. /* mptscsih_writeSDP1 - write SCSI Device Page 1
  2626. * @hd: Pointer to a SCSI Host Strucutre
  2627. * @portnum: IOC port number
  2628. * @target_id: writeSDP1 for single ID
  2629. * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
  2630. *
  2631. * Return: -EFAULT if read of config page header fails
  2632. * or 0 if success.
  2633. *
  2634. * Remark: If a target has been found, the settings from the
  2635. * target structure are used, else the device is set
  2636. * to async/narrow.
  2637. *
  2638. * Remark: Called during init and after a FW reload.
  2639. * Remark: We do not wait for a return, write pages sequentially.
  2640. */
  2641. static int
  2642. mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
  2643. {
  2644. MPT_ADAPTER *ioc = hd->ioc;
  2645. Config_t *pReq;
  2646. SCSIDevicePage1_t *pData;
  2647. VirtTarget *vtarget=NULL;
  2648. MPT_FRAME_HDR *mf;
  2649. dma_addr_t dataDma;
  2650. u16 req_idx;
  2651. u32 frameOffset;
  2652. u32 requested, configuration, flagsLength;
  2653. int ii, nvram;
  2654. int id = 0, maxid = 0;
  2655. u8 width;
  2656. u8 factor;
  2657. u8 offset;
  2658. u8 bus = 0;
  2659. u8 negoFlags;
  2660. u8 maxwidth, maxoffset, maxfactor;
  2661. if (ioc->spi_data.sdp1length == 0)
  2662. return 0;
  2663. if (flags & MPT_SCSICFG_ALL_IDS) {
  2664. id = 0;
  2665. maxid = ioc->sh->max_id - 1;
  2666. } else if (ioc->sh) {
  2667. id = target_id;
  2668. maxid = min_t(int, id, ioc->sh->max_id - 1);
  2669. }
  2670. for (; id <= maxid; id++) {
  2671. if (id == ioc->pfacts[portnum].PortSCSIID)
  2672. continue;
  2673. /* Use NVRAM to get adapter and target maximums
  2674. * Data over-riden by target structure information, if present
  2675. */
  2676. maxwidth = ioc->spi_data.maxBusWidth;
  2677. maxoffset = ioc->spi_data.maxSyncOffset;
  2678. maxfactor = ioc->spi_data.minSyncFactor;
  2679. if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
  2680. nvram = ioc->spi_data.nvram[id];
  2681. if (maxwidth)
  2682. maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
  2683. if (maxoffset > 0) {
  2684. maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
  2685. if (maxfactor == 0) {
  2686. /* Key for async */
  2687. maxfactor = MPT_ASYNC;
  2688. maxoffset = 0;
  2689. } else if (maxfactor < ioc->spi_data.minSyncFactor) {
  2690. maxfactor = ioc->spi_data.minSyncFactor;
  2691. }
  2692. } else
  2693. maxfactor = MPT_ASYNC;
  2694. }
  2695. /* Set the negotiation flags.
  2696. */
  2697. negoFlags = ioc->spi_data.noQas;
  2698. if (!maxwidth)
  2699. negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
  2700. if (!maxoffset)
  2701. negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
  2702. if (flags & MPT_SCSICFG_USE_NVRAM) {
  2703. width = maxwidth;
  2704. factor = maxfactor;
  2705. offset = maxoffset;
  2706. } else {
  2707. width = 0;
  2708. factor = MPT_ASYNC;
  2709. offset = 0;
  2710. //negoFlags = 0;
  2711. //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
  2712. }
  2713. /* If id is not a raid volume, get the updated
  2714. * transmission settings from the target structure.
  2715. */
  2716. if (hd->Targets && (vtarget = hd->Targets[id]) && !vtarget->raidVolume) {
  2717. width = vtarget->maxWidth;
  2718. factor = vtarget->minSyncFactor;
  2719. offset = vtarget->maxOffset;
  2720. negoFlags = vtarget->negoFlags;
  2721. }
  2722. #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
  2723. /* Force to async and narrow if DV has not been executed
  2724. * for this ID
  2725. */
  2726. if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
  2727. width = 0;
  2728. factor = MPT_ASYNC;
  2729. offset = 0;
  2730. }
  2731. #endif
  2732. if (flags & MPT_SCSICFG_BLK_NEGO)
  2733. negoFlags |= MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
  2734. mptscsih_setDevicePage1Flags(width, factor, offset,
  2735. &requested, &configuration, negoFlags);
  2736. dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
  2737. target_id, width, factor, offset, negoFlags, requested, configuration));
  2738. /* Get a MF for this command.
  2739. */
  2740. if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
  2741. dfailprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
  2742. ioc->name));
  2743. return -EAGAIN;
  2744. }
  2745. ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
  2746. hd->ioc->name, mf, id, requested, configuration));
  2747. /* Set the request and the data pointers.
  2748. * Request takes: 36 bytes (32 bit SGE)
  2749. * SCSI Device Page 1 requires 16 bytes
  2750. * 40 + 16 <= size of SCSI IO Request = 56 bytes
  2751. * and MF size >= 64 bytes.
  2752. * Place data at end of MF.
  2753. */
  2754. pReq = (Config_t *)mf;
  2755. req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
  2756. frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
  2757. pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
  2758. dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
  2759. /* Complete the request frame (same for all requests).
  2760. */
  2761. pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  2762. pReq->Reserved = 0;
  2763. pReq->ChainOffset = 0;
  2764. pReq->Function = MPI_FUNCTION_CONFIG;
  2765. pReq->ExtPageLength = 0;
  2766. pReq->ExtPageType = 0;
  2767. pReq->MsgFlags = 0;
  2768. for (ii=0; ii < 8; ii++) {
  2769. pReq->Reserved2[ii] = 0;
  2770. }
  2771. pReq->Header.PageVersion = ioc->spi_data.sdp1version;
  2772. pReq->Header.PageLength = ioc->spi_data.sdp1length;
  2773. pReq->Header.PageNumber = 1;
  2774. pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
  2775. pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
  2776. /* Add a SGE to the config request.
  2777. */
  2778. flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
  2779. mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
  2780. /* Set up the common data portion
  2781. */
  2782. pData->Header.PageVersion = pReq->Header.PageVersion;
  2783. pData->Header.PageLength = pReq->Header.PageLength;
  2784. pData->Header.PageNumber = pReq->Header.PageNumber;
  2785. pData->Header.PageType = pReq->Header.PageType;
  2786. pData->RequestedParameters = cpu_to_le32(requested);
  2787. pData->Reserved = 0;
  2788. pData->Configuration = cpu_to_le32(configuration);
  2789. dprintk((MYIOC_s_INFO_FMT
  2790. "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
  2791. ioc->name, id, (id | (bus<<8)),
  2792. requested, configuration));
  2793. mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
  2794. }
  2795. return 0;
  2796. }
  2797. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2798. /* mptscsih_writeIOCPage4 - write IOC Page 4
  2799. * @hd: Pointer to a SCSI Host Structure
  2800. * @target_id: write IOC Page4 for this ID & Bus
  2801. *
  2802. * Return: -EAGAIN if unable to obtain a Message Frame
  2803. * or 0 if success.
  2804. *
  2805. * Remark: We do not wait for a return, write pages sequentially.
  2806. */
  2807. static int
  2808. mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
  2809. {
  2810. MPT_ADAPTER *ioc = hd->ioc;
  2811. Config_t *pReq;
  2812. IOCPage4_t *IOCPage4Ptr;
  2813. MPT_FRAME_HDR *mf;
  2814. dma_addr_t dataDma;
  2815. u16 req_idx;
  2816. u32 frameOffset;
  2817. u32 flagsLength;
  2818. int ii;
  2819. /* Get a MF for this command.
  2820. */
  2821. if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
  2822. dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
  2823. ioc->name));
  2824. return -EAGAIN;
  2825. }
  2826. /* Set the request and the data pointers.
  2827. * Place data at end of MF.
  2828. */
  2829. pReq = (Config_t *)mf;
  2830. req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
  2831. frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
  2832. /* Complete the request frame (same for all requests).
  2833. */
  2834. pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  2835. pReq->Reserved = 0;
  2836. pReq->ChainOffset = 0;
  2837. pReq->Function = MPI_FUNCTION_CONFIG;
  2838. pReq->ExtPageLength = 0;
  2839. pReq->ExtPageType = 0;
  2840. pReq->MsgFlags = 0;
  2841. for (ii=0; ii < 8; ii++) {
  2842. pReq->Reserved2[ii] = 0;
  2843. }
  2844. IOCPage4Ptr = ioc->spi_data.pIocPg4;
  2845. dataDma = ioc->spi_data.IocPg4_dma;
  2846. ii = IOCPage4Ptr->ActiveSEP++;
  2847. IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
  2848. IOCPage4Ptr->SEP[ii].SEPBus = bus;
  2849. pReq->Header = IOCPage4Ptr->Header;
  2850. pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
  2851. /* Add a SGE to the config request.
  2852. */
  2853. flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
  2854. (IOCPage4Ptr->Header.PageLength + ii) * 4;
  2855. mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
  2856. dinitprintk((MYIOC_s_INFO_FMT
  2857. "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
  2858. ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
  2859. mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
  2860. return 0;
  2861. }
  2862. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2863. /*
  2864. * Bus Scan and Domain Validation functionality ...
  2865. */
  2866. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  2867. /*
  2868. * mptscsih_scandv_complete - Scan and DV callback routine registered
  2869. * to Fustion MPT (base) driver.
  2870. *
  2871. * @ioc: Pointer to MPT_ADAPTER structure
  2872. * @mf: Pointer to original MPT request frame
  2873. * @mr: Pointer to MPT reply frame (NULL if TurboReply)
  2874. *
  2875. * This routine is called from mpt.c::mpt_interrupt() at the completion
  2876. * of any SCSI IO request.
  2877. * This routine is registered with the Fusion MPT (base) driver at driver
  2878. * load/init time via the mpt_register() API call.
  2879. *
  2880. * Returns 1 indicating alloc'd request frame ptr should be freed.
  2881. *
  2882. * Remark: Sets a completion code and (possibly) saves sense data
  2883. * in the IOC member localReply structure.
  2884. * Used ONLY for DV and other internal commands.
  2885. */
  2886. int
  2887. mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
  2888. {
  2889. MPT_SCSI_HOST *hd;
  2890. SCSIIORequest_t *pReq;
  2891. int completionCode;
  2892. u16 req_idx;
  2893. hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
  2894. if ((mf == NULL) ||
  2895. (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
  2896. printk(MYIOC_s_ERR_FMT
  2897. "ScanDvComplete, %s req frame ptr! (=%p)\n",
  2898. ioc->name, mf?"BAD":"NULL", (void *) mf);
  2899. goto wakeup;
  2900. }
  2901. del_timer(&hd->timer);
  2902. req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
  2903. hd->ScsiLookup[req_idx] = NULL;
  2904. pReq = (SCSIIORequest_t *) mf;
  2905. if (mf != hd->cmdPtr) {
  2906. printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
  2907. hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
  2908. }
  2909. hd->cmdPtr = NULL;
  2910. ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
  2911. hd->ioc->name, mf, mr, req_idx));
  2912. hd->pLocal = &hd->localReply;
  2913. hd->pLocal->scsiStatus = 0;
  2914. /* If target struct exists, clear sense valid flag.
  2915. */
  2916. if (mr == NULL) {
  2917. completionCode = MPT_SCANDV_GOOD;
  2918. } else {
  2919. SCSIIOReply_t *pReply;
  2920. u16 status;
  2921. u8 scsi_status;
  2922. pReply = (SCSIIOReply_t *) mr;
  2923. status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
  2924. scsi_status = pReply->SCSIStatus;
  2925. ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
  2926. status, pReply->SCSIState, scsi_status,
  2927. le32_to_cpu(pReply->IOCLogInfo)));
  2928. switch(status) {
  2929. case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
  2930. completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
  2931. break;
  2932. case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
  2933. case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
  2934. case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
  2935. case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
  2936. completionCode = MPT_SCANDV_DID_RESET;
  2937. break;
  2938. case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
  2939. case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
  2940. case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
  2941. if (pReply->Function == MPI_FUNCTION_CONFIG) {
  2942. ConfigReply_t *pr = (ConfigReply_t *)mr;
  2943. completionCode = MPT_SCANDV_GOOD;
  2944. hd->pLocal->header.PageVersion = pr->Header.PageVersion;
  2945. hd->pLocal->header.PageLength = pr->Header.PageLength;
  2946. hd->pLocal->header.PageNumber = pr->Header.PageNumber;
  2947. hd->pLocal->header.PageType = pr->Header.PageType;
  2948. } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
  2949. /* If the RAID Volume request is successful,
  2950. * return GOOD, else indicate that
  2951. * some type of error occurred.
  2952. */
  2953. MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
  2954. if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
  2955. completionCode = MPT_SCANDV_GOOD;
  2956. else
  2957. completionCode = MPT_SCANDV_SOME_ERROR;
  2958. } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
  2959. u8 *sense_data;
  2960. int sz;
  2961. /* save sense data in global structure
  2962. */
  2963. completionCode = MPT_SCANDV_SENSE;
  2964. hd->pLocal->scsiStatus = scsi_status;
  2965. sense_data = ((u8 *)hd->ioc->sense_buf_pool +
  2966. (req_idx * MPT_SENSE_BUFFER_ALLOC));
  2967. sz = min_t(int, pReq->SenseBufferLength,
  2968. SCSI_STD_SENSE_BYTES);
  2969. memcpy(hd->pLocal->sense, sense_data, sz);
  2970. ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
  2971. sense_data));
  2972. } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
  2973. if (pReq->CDB[0] == INQUIRY)
  2974. completionCode = MPT_SCANDV_ISSUE_SENSE;
  2975. else
  2976. completionCode = MPT_SCANDV_DID_RESET;
  2977. }
  2978. else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
  2979. completionCode = MPT_SCANDV_DID_RESET;
  2980. else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
  2981. completionCode = MPT_SCANDV_DID_RESET;
  2982. else {
  2983. completionCode = MPT_SCANDV_GOOD;
  2984. hd->pLocal->scsiStatus = scsi_status;
  2985. }
  2986. break;
  2987. case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
  2988. if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
  2989. completionCode = MPT_SCANDV_DID_RESET;
  2990. else
  2991. completionCode = MPT_SCANDV_SOME_ERROR;
  2992. break;
  2993. default:
  2994. completionCode = MPT_SCANDV_SOME_ERROR;
  2995. break;
  2996. } /* switch(status) */
  2997. ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
  2998. completionCode));
  2999. } /* end of address reply case */
  3000. hd->pLocal->completion = completionCode;
  3001. /* MF and RF are freed in mpt_interrupt
  3002. */
  3003. wakeup:
  3004. /* Free Chain buffers (will never chain) in scan or dv */
  3005. //mptscsih_freeChainBuffers(ioc, req_idx);
  3006. /*
  3007. * Wake up the original calling thread
  3008. */
  3009. hd->scandv_wait_done = 1;
  3010. wake_up(&hd->scandv_waitq);
  3011. return 1;
  3012. }
  3013. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  3014. /* mptscsih_timer_expired - Call back for timer process.
  3015. * Used only for dv functionality.
  3016. * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
  3017. *
  3018. */
  3019. void
  3020. mptscsih_timer_expired(unsigned long data)
  3021. {
  3022. MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
  3023. ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
  3024. if (hd->cmdPtr) {
  3025. MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
  3026. if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
  3027. /* Desire to issue a task management request here.
  3028. * TM requests MUST be single threaded.
  3029. * If old eh code and no TM current, issue request.
  3030. * If new eh code, do nothing. Wait for OS cmd timeout
  3031. * for bus reset.
  3032. */
  3033. ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
  3034. } else {
  3035. /* Perform a FW reload */
  3036. if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
  3037. printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
  3038. }
  3039. }
  3040. } else {
  3041. /* This should NEVER happen */
  3042. printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
  3043. }
  3044. /* No more processing.
  3045. * TM call will generate an interrupt for SCSI TM Management.
  3046. * The FW will reply to all outstanding commands, callback will finish cleanup.
  3047. * Hard reset clean-up will free all resources.
  3048. */
  3049. ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
  3050. return;
  3051. }
  3052. #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
  3053. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  3054. /* mptscsih_do_raid - Format and Issue a RAID volume request message.
  3055. * @hd: Pointer to scsi host structure
  3056. * @action: What do be done.
  3057. * @id: Logical target id.
  3058. * @bus: Target locations bus.
  3059. *
  3060. * Returns: < 0 on a fatal error
  3061. * 0 on success
  3062. *
  3063. * Remark: Wait to return until reply processed by the ISR.
  3064. */
  3065. static int
  3066. mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
  3067. {
  3068. MpiRaidActionRequest_t *pReq;
  3069. MPT_FRAME_HDR *mf;
  3070. int in_isr;
  3071. in_isr = in_interrupt();
  3072. if (in_isr) {
  3073. dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
  3074. hd->ioc->name));
  3075. return -EPERM;
  3076. }
  3077. /* Get and Populate a free Frame
  3078. */
  3079. if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
  3080. ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
  3081. hd->ioc->name));
  3082. return -EAGAIN;
  3083. }
  3084. pReq = (MpiRaidActionRequest_t *)mf;
  3085. pReq->Action = action;
  3086. pReq->Reserved1 = 0;
  3087. pReq->ChainOffset = 0;
  3088. pReq->Function = MPI_FUNCTION_RAID_ACTION;
  3089. pReq->VolumeID = io->id;
  3090. pReq->VolumeBus = io->bus;
  3091. pReq->PhysDiskNum = io->physDiskNum;
  3092. pReq->MsgFlags = 0;
  3093. pReq->Reserved2 = 0;
  3094. pReq->ActionDataWord = 0; /* Reserved for this action */
  3095. //pReq->ActionDataSGE = 0;
  3096. mpt_add_sge((char *)&pReq->ActionDataSGE,
  3097. MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
  3098. ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
  3099. hd->ioc->name, action, io->id));
  3100. hd->pLocal = NULL;
  3101. hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
  3102. hd->scandv_wait_done = 0;
  3103. /* Save cmd pointer, for resource free if timeout or
  3104. * FW reload occurs
  3105. */
  3106. hd->cmdPtr = mf;
  3107. add_timer(&hd->timer);
  3108. mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
  3109. wait_event(hd->scandv_waitq, hd->scandv_wait_done);
  3110. if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
  3111. return -1;
  3112. return 0;
  3113. }
  3114. #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
  3115. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  3116. /**
  3117. * mptscsih_do_cmd - Do internal command.
  3118. * @hd: MPT_SCSI_HOST pointer
  3119. * @io: INTERNAL_CMD pointer.
  3120. *
  3121. * Issue the specified internally generated command and do command
  3122. * specific cleanup. For bus scan / DV only.
  3123. * NOTES: If command is Inquiry and status is good,
  3124. * initialize a target structure, save the data
  3125. *
  3126. * Remark: Single threaded access only.
  3127. *
  3128. * Return:
  3129. * < 0 if an illegal command or no resources
  3130. *
  3131. * 0 if good
  3132. *
  3133. * > 0 if command complete but some type of completion error.
  3134. */
  3135. static int
  3136. mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
  3137. {
  3138. MPT_FRAME_HDR *mf;
  3139. SCSIIORequest_t *pScsiReq;
  3140. SCSIIORequest_t ReqCopy;
  3141. int my_idx, ii, dir;
  3142. int rc, cmdTimeout;
  3143. int in_isr;
  3144. char cmdLen;
  3145. char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  3146. char cmd = io->cmd;
  3147. in_isr = in_interrupt();
  3148. if (in_isr) {
  3149. dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
  3150. hd->ioc->name));
  3151. return -EPERM;
  3152. }
  3153. /* Set command specific information
  3154. */
  3155. switch (cmd) {
  3156. case INQUIRY:
  3157. cmdLen = 6;
  3158. dir = MPI_SCSIIO_CONTROL_READ;
  3159. CDB[0] = cmd;
  3160. CDB[4] = io->size;
  3161. cmdTimeout = 10;
  3162. break;
  3163. case TEST_UNIT_READY:
  3164. cmdLen = 6;
  3165. dir = MPI_SCSIIO_CONTROL_READ;
  3166. cmdTimeout = 10;
  3167. break;
  3168. case START_STOP:
  3169. cmdLen = 6;
  3170. dir = MPI_SCSIIO_CONTROL_READ;
  3171. CDB[0] = cmd;
  3172. CDB[4] = 1; /*Spin up the disk */
  3173. cmdTimeout = 15;
  3174. break;
  3175. case REQUEST_SENSE:
  3176. cmdLen = 6;
  3177. CDB[0] = cmd;
  3178. CDB[4] = io->size;
  3179. dir = MPI_SCSIIO_CONTROL_READ;
  3180. cmdTimeout = 10;
  3181. break;
  3182. case READ_BUFFER:
  3183. cmdLen = 10;
  3184. dir = MPI_SCSIIO_CONTROL_READ;
  3185. CDB[0] = cmd;
  3186. if (io->flags & MPT_ICFLAG_ECHO) {
  3187. CDB[1] = 0x0A;
  3188. } else {
  3189. CDB[1] = 0x02;
  3190. }
  3191. if (io->flags & MPT_ICFLAG_BUF_CAP) {
  3192. CDB[1] |= 0x01;
  3193. }
  3194. CDB[6] = (io->size >> 16) & 0xFF;
  3195. CDB[7] = (io->size >> 8) & 0xFF;
  3196. CDB[8] = io->size & 0xFF;
  3197. cmdTimeout = 10;
  3198. break;
  3199. case WRITE_BUFFER:
  3200. cmdLen = 10;
  3201. dir = MPI_SCSIIO_CONTROL_WRITE;
  3202. CDB[0] = cmd;
  3203. if (io->flags & MPT_ICFLAG_ECHO) {
  3204. CDB[1] = 0x0A;
  3205. } else {
  3206. CDB[1] = 0x02;
  3207. }
  3208. CDB[6] = (io->size >> 16) & 0xFF;
  3209. CDB[7] = (io->size >> 8) & 0xFF;
  3210. CDB[8] = io->size & 0xFF;
  3211. cmdTimeout = 10;
  3212. break;
  3213. case RESERVE:
  3214. cmdLen = 6;
  3215. dir = MPI_SCSIIO_CONTROL_READ;
  3216. CDB[0] = cmd;
  3217. cmdTimeout = 10;
  3218. break;
  3219. case RELEASE:
  3220. cmdLen = 6;
  3221. dir = MPI_SCSIIO_CONTROL_READ;
  3222. CDB[0] = cmd;
  3223. cmdTimeout = 10;
  3224. break;
  3225. case SYNCHRONIZE_CACHE:
  3226. cmdLen = 10;
  3227. dir = MPI_SCSIIO_CONTROL_READ;
  3228. CDB[0] = cmd;
  3229. // CDB[1] = 0x02; /* set immediate bit */
  3230. cmdTimeout = 10;
  3231. break;
  3232. default:
  3233. /* Error Case */
  3234. return -EFAULT;
  3235. }
  3236. /* Get and Populate a free Frame
  3237. */
  3238. if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
  3239. ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
  3240. hd->ioc->name));
  3241. return -EBUSY;
  3242. }
  3243. pScsiReq = (SCSIIORequest_t *) mf;
  3244. /* Get the request index */
  3245. my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
  3246. ADD_INDEX_LOG(my_idx); /* for debug */
  3247. if (io->flags & MPT_ICFLAG_PHYS_DISK) {
  3248. pScsiReq->TargetID = io->physDiskNum;
  3249. pScsiReq->Bus = 0;
  3250. pScsiReq->ChainOffset = 0;
  3251. pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
  3252. } else {
  3253. pScsiReq->TargetID = io->id;
  3254. pScsiReq->Bus = io->bus;
  3255. pScsiReq->ChainOffset = 0;
  3256. pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
  3257. }
  3258. pScsiReq->CDBLength = cmdLen;
  3259. pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
  3260. pScsiReq->Reserved = 0;
  3261. pScsiReq->MsgFlags = mpt_msg_flags();
  3262. /* MsgContext set in mpt_get_msg_fram call */
  3263. for (ii=0; ii < 8; ii++)
  3264. pScsiReq->LUN[ii] = 0;
  3265. pScsiReq->LUN[1] = io->lun;
  3266. if (io->flags & MPT_ICFLAG_TAGGED_CMD)
  3267. pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
  3268. else
  3269. pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
  3270. if (cmd == REQUEST_SENSE) {
  3271. pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
  3272. ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
  3273. hd->ioc->name, cmd));
  3274. }
  3275. for (ii=0; ii < 16; ii++)
  3276. pScsiReq->CDB[ii] = CDB[ii];
  3277. pScsiReq->DataLength = cpu_to_le32(io->size);
  3278. pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
  3279. + (my_idx * MPT_SENSE_BUFFER_ALLOC));
  3280. ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
  3281. hd->ioc->name, cmd, io->bus, io->id, io->lun));
  3282. if (dir == MPI_SCSIIO_CONTROL_READ) {
  3283. mpt_add_sge((char *) &pScsiReq->SGL,
  3284. MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
  3285. io->data_dma);
  3286. } else {
  3287. mpt_add_sge((char *) &pScsiReq->SGL,
  3288. MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
  3289. io->data_dma);
  3290. }
  3291. /* The ISR will free the request frame, but we need
  3292. * the information to initialize the target. Duplicate.
  3293. */
  3294. memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
  3295. /* Issue this command after:
  3296. * finish init
  3297. * add timer
  3298. * Wait until the reply has been received
  3299. * ScsiScanDvCtx callback function will
  3300. * set hd->pLocal;
  3301. * set scandv_wait_done and call wake_up
  3302. */
  3303. hd->pLocal = NULL;
  3304. hd->timer.expires = jiffies + HZ*cmdTimeout;
  3305. hd->scandv_wait_done = 0;
  3306. /* Save cmd pointer, for resource free if timeout or
  3307. * FW reload occurs
  3308. */
  3309. hd->cmdPtr = mf;
  3310. add_timer(&hd->timer);
  3311. mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
  3312. wait_event(hd->scandv_waitq, hd->scandv_wait_done);
  3313. if (hd->pLocal) {
  3314. rc = hd->pLocal->completion;
  3315. hd->pLocal->skip = 0;
  3316. /* Always set fatal error codes in some cases.
  3317. */
  3318. if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
  3319. rc = -ENXIO;
  3320. else if (rc == MPT_SCANDV_SOME_ERROR)
  3321. rc = -rc;
  3322. } else {
  3323. rc = -EFAULT;
  3324. /* This should never happen. */
  3325. ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
  3326. hd->ioc->name));
  3327. }
  3328. return rc;
  3329. }
  3330. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  3331. /**
  3332. * mptscsih_negotiate_to_asyn_narrow - Restore devices to default state
  3333. * @hd: Pointer to a SCSI HOST structure
  3334. * @vtarget: per device private data
  3335. *
  3336. * Uses the ISR, but with special processing.
  3337. * MUST be single-threaded.
  3338. *
  3339. */
  3340. static void
  3341. mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget)
  3342. {
  3343. MPT_ADAPTER *ioc= hd->ioc;
  3344. SCSIDevicePage1_t *pcfg1Data;
  3345. CONFIGPARMS cfg;
  3346. dma_addr_t cfg1_dma_addr;
  3347. ConfigPageHeader_t header;
  3348. int id;
  3349. int requested, configuration, data,i;
  3350. u8 flags, factor;
  3351. if (ioc->bus_type != SPI)
  3352. return;
  3353. if (!ioc->spi_data.sdp1length)
  3354. return;
  3355. pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
  3356. ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
  3357. if (pcfg1Data == NULL)
  3358. return;
  3359. header.PageVersion = ioc->spi_data.sdp1version;
  3360. header.PageLength = ioc->spi_data.sdp1length;
  3361. header.PageNumber = 1;
  3362. header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
  3363. cfg.cfghdr.hdr = &header;
  3364. cfg.physAddr = cfg1_dma_addr;
  3365. cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  3366. cfg.dir = 1;
  3367. cfg.timeout = 0;
  3368. if (vtarget->raidVolume && ioc->raid_data.pIocPg3) {
  3369. for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
  3370. id = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID;
  3371. flags = hd->ioc->spi_data.noQas;
  3372. if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
  3373. data = hd->ioc->spi_data.nvram[id];
  3374. if (data & MPT_NVRAM_WIDE_DISABLE)
  3375. flags |= MPT_TARGET_NO_NEGO_WIDE;
  3376. factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
  3377. if ((factor == 0) || (factor == MPT_ASYNC))
  3378. flags |= MPT_TARGET_NO_NEGO_SYNC;
  3379. }
  3380. mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
  3381. &configuration, flags);
  3382. dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
  3383. "offset=0 negoFlags=%x request=%x config=%x\n",
  3384. id, flags, requested, configuration));
  3385. pcfg1Data->RequestedParameters = cpu_to_le32(requested);
  3386. pcfg1Data->Reserved = 0;
  3387. pcfg1Data->Configuration = cpu_to_le32(configuration);
  3388. cfg.pageAddr = (vtarget->bus_id<<8) | id;
  3389. mpt_config(hd->ioc, &cfg);
  3390. }
  3391. } else {
  3392. flags = vtarget->negoFlags;
  3393. mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
  3394. &configuration, flags);
  3395. dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
  3396. "offset=0 negoFlags=%x request=%x config=%x\n",
  3397. vtarget->target_id, flags, requested, configuration));
  3398. pcfg1Data->RequestedParameters = cpu_to_le32(requested);
  3399. pcfg1Data->Reserved = 0;
  3400. pcfg1Data->Configuration = cpu_to_le32(configuration);
  3401. cfg.pageAddr = (vtarget->bus_id<<8) | vtarget->target_id;
  3402. mpt_config(hd->ioc, &cfg);
  3403. }
  3404. if (pcfg1Data)
  3405. pci_free_consistent(ioc->pcidev, header.PageLength * 4, pcfg1Data, cfg1_dma_addr);
  3406. }
  3407. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  3408. /**
  3409. * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
  3410. * @hd: Pointer to a SCSI HOST structure
  3411. * @vtarget: per device private data
  3412. * @lun: lun
  3413. *
  3414. * Uses the ISR, but with special processing.
  3415. * MUST be single-threaded.
  3416. *
  3417. */
  3418. static void
  3419. mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
  3420. {
  3421. INTERNAL_CMD iocmd;
  3422. /* Following parameters will not change
  3423. * in this routine.
  3424. */
  3425. iocmd.cmd = SYNCHRONIZE_CACHE;
  3426. iocmd.flags = 0;
  3427. iocmd.physDiskNum = -1;
  3428. iocmd.data = NULL;
  3429. iocmd.data_dma = -1;
  3430. iocmd.size = 0;
  3431. iocmd.rsvd = iocmd.rsvd2 = 0;
  3432. iocmd.bus = vdevice->bus_id;
  3433. iocmd.id = vdevice->target_id;
  3434. iocmd.lun = (u8)vdevice->lun;
  3435. if ((vdevice->vtarget->type & TYPE_DISK) &&
  3436. (vdevice->configured_lun))
  3437. mptscsih_do_cmd(hd, &iocmd);
  3438. }
  3439. /* Search IOC page 3 to determine if this is hidden physical disk
  3440. */
  3441. static int
  3442. mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
  3443. {
  3444. int i;
  3445. if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3)
  3446. return 0;
  3447. for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
  3448. if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID)
  3449. return 1;
  3450. }
  3451. return 0;
  3452. }
  3453. #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
  3454. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  3455. /**
  3456. * mptscsih_domainValidation - Top level handler for domain validation.
  3457. * @hd: Pointer to MPT_SCSI_HOST structure.
  3458. *
  3459. * Uses the ISR, but with special processing.
  3460. * Called from schedule, should not be in interrupt mode.
  3461. * While thread alive, do dv for all devices needing dv
  3462. *
  3463. * Return: None.
  3464. */
  3465. static void
  3466. mptscsih_domainValidation(void *arg)
  3467. {
  3468. MPT_SCSI_HOST *hd;
  3469. MPT_ADAPTER *ioc;
  3470. unsigned long flags;
  3471. int id, maxid, dvStatus, did;
  3472. int ii, isPhysDisk;
  3473. spin_lock_irqsave(&dvtaskQ_lock, flags);
  3474. dvtaskQ_active = 1;
  3475. if (dvtaskQ_release) {
  3476. dvtaskQ_active = 0;
  3477. spin_unlock_irqrestore(&dvtaskQ_lock, flags);
  3478. return;
  3479. }
  3480. spin_unlock_irqrestore(&dvtaskQ_lock, flags);
  3481. /* For this ioc, loop through all devices and do dv to each device.
  3482. * When complete with this ioc, search through the ioc list, and
  3483. * for each scsi ioc found, do dv for all devices. Exit when no
  3484. * device needs dv.
  3485. */
  3486. did = 1;
  3487. while (did) {
  3488. did = 0;
  3489. list_for_each_entry(ioc, &ioc_list, list) {
  3490. spin_lock_irqsave(&dvtaskQ_lock, flags);
  3491. if (dvtaskQ_release) {
  3492. dvtaskQ_active = 0;
  3493. spin_unlock_irqrestore(&dvtaskQ_lock, flags);
  3494. return;
  3495. }
  3496. spin_unlock_irqrestore(&dvtaskQ_lock, flags);
  3497. msleep(250);
  3498. /* DV only to SPI adapters */
  3499. if (ioc->bus_type != SPI)
  3500. continue;
  3501. /* Make sure everything looks ok */
  3502. if (ioc->sh == NULL)
  3503. continue;
  3504. hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
  3505. if (hd == NULL)
  3506. continue;
  3507. if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
  3508. mpt_read_ioc_pg_3(ioc);
  3509. if (ioc->raid_data.pIocPg3) {
  3510. Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
  3511. int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
  3512. while (numPDisk) {
  3513. if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
  3514. ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
  3515. pPDisk++;
  3516. numPDisk--;
  3517. }
  3518. }
  3519. ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3;
  3520. }
  3521. maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
  3522. for (id = 0; id < maxid; id++) {
  3523. spin_lock_irqsave(&dvtaskQ_lock, flags);
  3524. if (dvtaskQ_release) {
  3525. dvtaskQ_active = 0;
  3526. spin_unlock_irqrestore(&dvtaskQ_lock, flags);
  3527. return;
  3528. }
  3529. spin_unlock_irqrestore(&dvtaskQ_lock, flags);
  3530. dvStatus = hd->ioc->spi_data.dvStatus[id];
  3531. if (dvStatus & MPT_SCSICFG_NEED_DV) {
  3532. did++;
  3533. hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
  3534. hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
  3535. msleep(250);
  3536. /* If hidden phys disk, block IO's to all
  3537. * raid volumes
  3538. * else, process normally
  3539. */
  3540. isPhysDisk = mptscsih_is_phys_disk(ioc, id);
  3541. if (isPhysDisk) {
  3542. for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
  3543. if (hd->ioc->raid_data.isRaid & (1 << ii)) {
  3544. hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
  3545. }
  3546. }
  3547. }
  3548. if(mpt_alt_ioc_wait(hd->ioc)!=0) {
  3549. ddvprintk((MYIOC_s_WARN_FMT "alt_ioc busy!\n",
  3550. hd->ioc->name));
  3551. continue;
  3552. }
  3553. if (mptscsih_doDv(hd, 0, id) == 1) {
  3554. /* Untagged device was busy, try again
  3555. */
  3556. hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV;
  3557. hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
  3558. } else {
  3559. /* DV is complete. Clear flags.
  3560. */
  3561. hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
  3562. }
  3563. spin_lock(&hd->ioc->initializing_hba_lock);
  3564. hd->ioc->initializing_hba_lock_flag=0;
  3565. spin_unlock(&hd->ioc->initializing_hba_lock);
  3566. if (isPhysDisk) {
  3567. for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
  3568. if (hd->ioc->raid_data.isRaid & (1 << ii)) {
  3569. hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
  3570. }
  3571. }
  3572. }
  3573. if (hd->ioc->spi_data.noQas)
  3574. mptscsih_qas_check(hd, id);
  3575. }
  3576. }
  3577. }
  3578. }
  3579. spin_lock_irqsave(&dvtaskQ_lock, flags);
  3580. dvtaskQ_active = 0;
  3581. spin_unlock_irqrestore(&dvtaskQ_lock, flags);
  3582. return;
  3583. }
  3584. /* Write SDP1 if no QAS has been enabled
  3585. */
  3586. static void
  3587. mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
  3588. {
  3589. VirtTarget *vtarget;
  3590. int ii;
  3591. if (hd->Targets == NULL)
  3592. return;
  3593. for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
  3594. if (ii == id)
  3595. continue;
  3596. if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
  3597. continue;
  3598. vtarget = hd->Targets[ii];
  3599. if ((vtarget != NULL) && (!vtarget->raidVolume)) {
  3600. if ((vtarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
  3601. vtarget->negoFlags |= hd->ioc->spi_data.noQas;
  3602. dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
  3603. mptscsih_writeSDP1(hd, 0, ii, 0);
  3604. }
  3605. } else {
  3606. if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) {
  3607. dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id));
  3608. mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
  3609. }
  3610. }
  3611. }
  3612. return;
  3613. }
  3614. #define MPT_GET_NVRAM_VALS 0x01
  3615. #define MPT_UPDATE_MAX 0x02
  3616. #define MPT_SET_MAX 0x04
  3617. #define MPT_SET_MIN 0x08
  3618. #define MPT_FALLBACK 0x10
  3619. #define MPT_SAVE 0x20
  3620. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  3621. /**
  3622. * mptscsih_doDv - Perform domain validation to a target.
  3623. * @hd: Pointer to MPT_SCSI_HOST structure.
  3624. * @portnum: IOC port number.
  3625. * @target: Physical ID of this target
  3626. *
  3627. * Uses the ISR, but with special processing.
  3628. * MUST be single-threaded.
  3629. * Test will exit if target is at async & narrow.
  3630. *
  3631. * Return: None.
  3632. */
  3633. static int
  3634. mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
  3635. {
  3636. MPT_ADAPTER *ioc = hd->ioc;
  3637. VirtTarget *vtarget;
  3638. SCSIDevicePage1_t *pcfg1Data;
  3639. SCSIDevicePage0_t *pcfg0Data;
  3640. u8 *pbuf1;
  3641. u8 *pbuf2;
  3642. u8 *pDvBuf;
  3643. dma_addr_t dvbuf_dma = -1;
  3644. dma_addr_t buf1_dma = -1;
  3645. dma_addr_t buf2_dma = -1;
  3646. dma_addr_t cfg1_dma_addr = -1;
  3647. dma_addr_t cfg0_dma_addr = -1;
  3648. ConfigPageHeader_t header1;
  3649. ConfigPageHeader_t header0;
  3650. DVPARAMETERS dv;
  3651. INTERNAL_CMD iocmd;
  3652. CONFIGPARMS cfg;
  3653. int dv_alloc = 0;
  3654. int rc, sz = 0;
  3655. int bufsize = 0;
  3656. int dataBufSize = 0;
  3657. int echoBufSize = 0;
  3658. int notDone;
  3659. int patt;
  3660. int repeat;
  3661. int retcode = 0;
  3662. int nfactor = MPT_ULTRA320;
  3663. char firstPass = 1;
  3664. char doFallback = 0;
  3665. char readPage0;
  3666. char bus, lun;
  3667. char inq0 = 0;
  3668. if (ioc->spi_data.sdp1length == 0)
  3669. return 0;
  3670. if (ioc->spi_data.sdp0length == 0)
  3671. return 0;
  3672. /* If multiple buses are used, require that the initiator
  3673. * id be the same on all buses.
  3674. */
  3675. if (id == ioc->pfacts[0].PortSCSIID)
  3676. return 0;
  3677. lun = 0;
  3678. bus = (u8) bus_number;
  3679. ddvtprintk((MYIOC_s_NOTE_FMT
  3680. "DV started: bus=%d, id=%d dv @ %p\n",
  3681. ioc->name, bus, id, &dv));
  3682. /* Prep DV structure
  3683. */
  3684. memset (&dv, 0, sizeof(DVPARAMETERS));
  3685. dv.id = id;
  3686. /* Populate tmax with the current maximum
  3687. * transfer parameters for this target.
  3688. * Exit if narrow and async.
  3689. */
  3690. dv.cmd = MPT_GET_NVRAM_VALS;
  3691. mptscsih_dv_parms(hd, &dv, NULL);
  3692. /* Prep SCSI IO structure
  3693. */
  3694. iocmd.id = id;
  3695. iocmd.bus = bus;
  3696. iocmd.lun = lun;
  3697. iocmd.flags = 0;
  3698. iocmd.physDiskNum = -1;
  3699. iocmd.rsvd = iocmd.rsvd2 = 0;
  3700. vtarget = hd->Targets[id];
  3701. /* Use tagged commands if possible.
  3702. */
  3703. if (vtarget) {
  3704. if (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
  3705. iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
  3706. else {
  3707. if (hd->ioc->facts.FWVersion.Word < 0x01000600)
  3708. return 0;
  3709. if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
  3710. (hd->ioc->facts.FWVersion.Word < 0x01010B00))
  3711. return 0;
  3712. }
  3713. }
  3714. /* Prep cfg structure
  3715. */
  3716. cfg.pageAddr = (bus<<8) | id;
  3717. cfg.cfghdr.hdr = NULL;
  3718. /* Prep SDP0 header
  3719. */
  3720. header0.PageVersion = ioc->spi_data.sdp0version;
  3721. header0.PageLength = ioc->spi_data.sdp0length;
  3722. header0.PageNumber = 0;
  3723. header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
  3724. /* Prep SDP1 header
  3725. */
  3726. header1.PageVersion = ioc->spi_data.sdp1version;
  3727. header1.PageLength = ioc->spi_data.sdp1length;
  3728. header1.PageNumber = 1;
  3729. header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
  3730. if (header0.PageLength & 1)
  3731. dv_alloc = (header0.PageLength * 4) + 4;
  3732. dv_alloc += (2048 + (header1.PageLength * 4));
  3733. pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma);
  3734. if (pDvBuf == NULL)
  3735. return 0;
  3736. sz = 0;
  3737. pbuf1 = (u8 *)pDvBuf;
  3738. buf1_dma = dvbuf_dma;
  3739. sz +=1024;
  3740. pbuf2 = (u8 *) (pDvBuf + sz);
  3741. buf2_dma = dvbuf_dma + sz;
  3742. sz +=1024;
  3743. pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz);
  3744. cfg0_dma_addr = dvbuf_dma + sz;
  3745. sz += header0.PageLength * 4;
  3746. /* 8-byte alignment
  3747. */
  3748. if (header0.PageLength & 1)
  3749. sz += 4;
  3750. pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
  3751. cfg1_dma_addr = dvbuf_dma + sz;
  3752. /* Skip this ID? Set cfg.cfghdr.hdr to force config page write
  3753. */
  3754. {
  3755. SpiCfgData *pspi_data = &hd->ioc->spi_data;
  3756. if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
  3757. /* Set the factor from nvram */
  3758. nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
  3759. if (nfactor < pspi_data->minSyncFactor )
  3760. nfactor = pspi_data->minSyncFactor;
  3761. if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
  3762. (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
  3763. ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
  3764. ioc->name, bus, id, lun));
  3765. dv.cmd = MPT_SET_MAX;
  3766. mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
  3767. cfg.cfghdr.hdr = &header1;
  3768. /* Save the final negotiated settings to
  3769. * SCSI device page 1.
  3770. */
  3771. cfg.physAddr = cfg1_dma_addr;
  3772. cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  3773. cfg.dir = 1;
  3774. mpt_config(hd->ioc, &cfg);
  3775. goto target_done;
  3776. }
  3777. }
  3778. }
  3779. /* Finish iocmd inititialization - hidden or visible disk? */
  3780. if (ioc->raid_data.pIocPg3) {
  3781. /* Search IOC page 3 for matching id
  3782. */
  3783. Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
  3784. int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
  3785. while (numPDisk) {
  3786. if (pPDisk->PhysDiskID == id) {
  3787. /* match */
  3788. iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
  3789. iocmd.physDiskNum = pPDisk->PhysDiskNum;
  3790. /* Quiesce the IM
  3791. */
  3792. if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
  3793. ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
  3794. goto target_done;
  3795. }
  3796. break;
  3797. }
  3798. pPDisk++;
  3799. numPDisk--;
  3800. }
  3801. }
  3802. /* RAID Volume ID's may double for a physical device. If RAID but
  3803. * not a physical ID as well, skip DV.
  3804. */
  3805. if ((hd->ioc->raid_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
  3806. goto target_done;
  3807. /* Basic Test.
  3808. * Async & Narrow - Inquiry
  3809. * Async & Narrow - Inquiry
  3810. * Maximum transfer rate - Inquiry
  3811. * Compare buffers:
  3812. * If compare, test complete.
  3813. * If miscompare and first pass, repeat
  3814. * If miscompare and not first pass, fall back and repeat
  3815. */
  3816. hd->pLocal = NULL;
  3817. readPage0 = 0;
  3818. sz = SCSI_MAX_INQUIRY_BYTES;
  3819. rc = MPT_SCANDV_GOOD;
  3820. while (1) {
  3821. ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
  3822. retcode = 0;
  3823. dv.cmd = MPT_SET_MIN;
  3824. mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
  3825. cfg.cfghdr.hdr = &header1;
  3826. cfg.physAddr = cfg1_dma_addr;
  3827. cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  3828. cfg.dir = 1;
  3829. if (mpt_config(hd->ioc, &cfg) != 0)
  3830. goto target_done;
  3831. /* Wide - narrow - wide workaround case
  3832. */
  3833. if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) {
  3834. /* Send an untagged command to reset disk Qs corrupted
  3835. * when a parity error occurs on a Request Sense.
  3836. */
  3837. if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) ||
  3838. ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
  3839. (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
  3840. iocmd.cmd = REQUEST_SENSE;
  3841. iocmd.data_dma = buf1_dma;
  3842. iocmd.data = pbuf1;
  3843. iocmd.size = 0x12;
  3844. if (mptscsih_do_cmd(hd, &iocmd) < 0)
  3845. goto target_done;
  3846. else {
  3847. if (hd->pLocal == NULL)
  3848. goto target_done;
  3849. rc = hd->pLocal->completion;
  3850. if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
  3851. dv.max.width = 0;
  3852. doFallback = 0;
  3853. } else
  3854. goto target_done;
  3855. }
  3856. } else
  3857. goto target_done;
  3858. }
  3859. iocmd.cmd = INQUIRY;
  3860. iocmd.data_dma = buf1_dma;
  3861. iocmd.data = pbuf1;
  3862. iocmd.size = sz;
  3863. memset(pbuf1, 0x00, sz);
  3864. if (mptscsih_do_cmd(hd, &iocmd) < 0)
  3865. goto target_done;
  3866. else {
  3867. if (hd->pLocal == NULL)
  3868. goto target_done;
  3869. rc = hd->pLocal->completion;
  3870. if (rc == MPT_SCANDV_GOOD) {
  3871. if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) {
  3872. if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
  3873. retcode = 1;
  3874. else
  3875. retcode = 0;
  3876. goto target_done;
  3877. }
  3878. } else if (rc == MPT_SCANDV_SENSE) {
  3879. ;
  3880. } else {
  3881. /* If first command doesn't complete
  3882. * with a good status or with a check condition,
  3883. * exit.
  3884. */
  3885. goto target_done;
  3886. }
  3887. }
  3888. /* Reset the size for disks
  3889. */
  3890. inq0 = (*pbuf1) & 0x1F;
  3891. if ((inq0 == 0) && vtarget && !vtarget->raidVolume) {
  3892. sz = 0x40;
  3893. iocmd.size = sz;
  3894. }
  3895. /* Another GEM workaround. Check peripheral device type,
  3896. * if PROCESSOR, quit DV.
  3897. */
  3898. if (inq0 == TYPE_PROCESSOR) {
  3899. mptscsih_initTarget(hd,
  3900. vtarget,
  3901. lun,
  3902. pbuf1,
  3903. sz);
  3904. goto target_done;
  3905. }
  3906. if (inq0 > 0x08)
  3907. goto target_done;
  3908. if (mptscsih_do_cmd(hd, &iocmd) < 0)
  3909. goto target_done;
  3910. if (sz == 0x40) {
  3911. if ((vtarget->maxWidth == 1) && (vtarget->maxOffset) && (nfactor < 0x0A)
  3912. && (vtarget->minSyncFactor > 0x09)) {
  3913. if ((pbuf1[56] & 0x04) == 0)
  3914. ;
  3915. else if ((pbuf1[56] & 0x01) == 1) {
  3916. vtarget->minSyncFactor =
  3917. nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
  3918. } else {
  3919. vtarget->minSyncFactor =
  3920. nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
  3921. }
  3922. dv.max.factor = vtarget->minSyncFactor;
  3923. if ((pbuf1[56] & 0x02) == 0) {
  3924. vtarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
  3925. hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
  3926. ddvprintk((MYIOC_s_NOTE_FMT
  3927. "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
  3928. ioc->name, id, pbuf1[56]));
  3929. }
  3930. }
  3931. }
  3932. if (doFallback)
  3933. dv.cmd = MPT_FALLBACK;
  3934. else
  3935. dv.cmd = MPT_SET_MAX;
  3936. mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
  3937. if (mpt_config(hd->ioc, &cfg) != 0)
  3938. goto target_done;
  3939. if ((!dv.now.width) && (!dv.now.offset))
  3940. goto target_done;
  3941. iocmd.cmd = INQUIRY;
  3942. iocmd.data_dma = buf2_dma;
  3943. iocmd.data = pbuf2;
  3944. iocmd.size = sz;
  3945. memset(pbuf2, 0x00, sz);
  3946. if (mptscsih_do_cmd(hd, &iocmd) < 0)
  3947. goto target_done;
  3948. else if (hd->pLocal == NULL)
  3949. goto target_done;
  3950. else {
  3951. /* Save the return code.
  3952. * If this is the first pass,
  3953. * read SCSI Device Page 0
  3954. * and update the target max parameters.
  3955. */
  3956. rc = hd->pLocal->completion;
  3957. doFallback = 0;
  3958. if (rc == MPT_SCANDV_GOOD) {
  3959. if (!readPage0) {
  3960. u32 sdp0_info;
  3961. u32 sdp0_nego;
  3962. cfg.cfghdr.hdr = &header0;
  3963. cfg.physAddr = cfg0_dma_addr;
  3964. cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
  3965. cfg.dir = 0;
  3966. if (mpt_config(hd->ioc, &cfg) != 0)
  3967. goto target_done;
  3968. sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
  3969. sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
  3970. /* Quantum and Fujitsu workarounds.
  3971. * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
  3972. * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
  3973. * Resetart with a request for U160.
  3974. */
  3975. if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) {
  3976. doFallback = 1;
  3977. } else {
  3978. dv.cmd = MPT_UPDATE_MAX;
  3979. mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
  3980. /* Update the SCSI device page 1 area
  3981. */
  3982. pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
  3983. readPage0 = 1;
  3984. }
  3985. }
  3986. /* Quantum workaround. Restart this test will the fallback
  3987. * flag set.
  3988. */
  3989. if (doFallback == 0) {
  3990. if (memcmp(pbuf1, pbuf2, sz) != 0) {
  3991. if (!firstPass)
  3992. doFallback = 1;
  3993. } else {
  3994. ddvprintk((MYIOC_s_NOTE_FMT
  3995. "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
  3996. hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
  3997. mptscsih_initTarget(hd,
  3998. vtarget,
  3999. lun,
  4000. pbuf1,
  4001. sz);
  4002. break; /* test complete */
  4003. }
  4004. }
  4005. } else if (rc == MPT_SCANDV_ISSUE_SENSE)
  4006. doFallback = 1; /* set fallback flag */
  4007. else if ((rc == MPT_SCANDV_DID_RESET) ||
  4008. (rc == MPT_SCANDV_SENSE) ||
  4009. (rc == MPT_SCANDV_FALLBACK))
  4010. doFallback = 1; /* set fallback flag */
  4011. else
  4012. goto target_done;
  4013. firstPass = 0;
  4014. }
  4015. }
  4016. ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
  4017. if (ioc->spi_data.mpt_dv == 0)
  4018. goto target_done;
  4019. inq0 = (*pbuf1) & 0x1F;
  4020. /* Continue only for disks
  4021. */
  4022. if (inq0 != 0)
  4023. goto target_done;
  4024. if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
  4025. goto target_done;
  4026. /* Start the Enhanced Test.
  4027. * 0) issue TUR to clear out check conditions
  4028. * 1) read capacity of echo (regular) buffer
  4029. * 2) reserve device
  4030. * 3) do write-read-compare data pattern test
  4031. * 4) release
  4032. * 5) update nego parms to target struct
  4033. */
  4034. cfg.cfghdr.hdr = &header1;
  4035. cfg.physAddr = cfg1_dma_addr;
  4036. cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  4037. cfg.dir = 1;
  4038. iocmd.cmd = TEST_UNIT_READY;
  4039. iocmd.data_dma = -1;
  4040. iocmd.data = NULL;
  4041. iocmd.size = 0;
  4042. notDone = 1;
  4043. while (notDone) {
  4044. if (mptscsih_do_cmd(hd, &iocmd) < 0)
  4045. goto target_done;
  4046. if (hd->pLocal == NULL)
  4047. goto target_done;
  4048. rc = hd->pLocal->completion;
  4049. if (rc == MPT_SCANDV_GOOD)
  4050. notDone = 0;
  4051. else if (rc == MPT_SCANDV_SENSE) {
  4052. u8 skey = hd->pLocal->sense[2] & 0x0F;
  4053. u8 asc = hd->pLocal->sense[12];
  4054. u8 ascq = hd->pLocal->sense[13];
  4055. ddvprintk((MYIOC_s_INFO_FMT
  4056. "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
  4057. ioc->name, skey, asc, ascq));
  4058. if (skey == UNIT_ATTENTION)
  4059. notDone++; /* repeat */
  4060. else if ((skey == NOT_READY) &&
  4061. (asc == 0x04)&&(ascq == 0x01)) {
  4062. /* wait then repeat */
  4063. mdelay (2000);
  4064. notDone++;
  4065. } else if ((skey == NOT_READY) && (asc == 0x3A)) {
  4066. /* no medium, try read test anyway */
  4067. notDone = 0;
  4068. } else {
  4069. /* All other errors are fatal.
  4070. */
  4071. ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
  4072. ioc->name));
  4073. goto target_done;
  4074. }
  4075. } else
  4076. goto target_done;
  4077. }
  4078. iocmd.cmd = READ_BUFFER;
  4079. iocmd.data_dma = buf1_dma;
  4080. iocmd.data = pbuf1;
  4081. iocmd.size = 4;
  4082. iocmd.flags |= MPT_ICFLAG_BUF_CAP;
  4083. dataBufSize = 0;
  4084. echoBufSize = 0;
  4085. for (patt = 0; patt < 2; patt++) {
  4086. if (patt == 0)
  4087. iocmd.flags |= MPT_ICFLAG_ECHO;
  4088. else
  4089. iocmd.flags &= ~MPT_ICFLAG_ECHO;
  4090. notDone = 1;
  4091. while (notDone) {
  4092. bufsize = 0;
  4093. /* If not ready after 8 trials,
  4094. * give up on this device.
  4095. */
  4096. if (notDone > 8)
  4097. goto target_done;
  4098. if (mptscsih_do_cmd(hd, &iocmd) < 0)
  4099. goto target_done;
  4100. else if (hd->pLocal == NULL)
  4101. goto target_done;
  4102. else {
  4103. rc = hd->pLocal->completion;
  4104. ddvprintk(("ReadBuffer Comp Code %d", rc));
  4105. ddvprintk((" buff: %0x %0x %0x %0x\n",
  4106. pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
  4107. if (rc == MPT_SCANDV_GOOD) {
  4108. notDone = 0;
  4109. if (iocmd.flags & MPT_ICFLAG_ECHO) {
  4110. bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
  4111. if (pbuf1[0] & 0x01)
  4112. iocmd.flags |= MPT_ICFLAG_EBOS;
  4113. } else {
  4114. bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
  4115. }
  4116. } else if (rc == MPT_SCANDV_SENSE) {
  4117. u8 skey = hd->pLocal->sense[2] & 0x0F;
  4118. u8 asc = hd->pLocal->sense[12];
  4119. u8 ascq = hd->pLocal->sense[13];
  4120. ddvprintk((MYIOC_s_INFO_FMT
  4121. "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
  4122. ioc->name, skey, asc, ascq));
  4123. if (skey == ILLEGAL_REQUEST) {
  4124. notDone = 0;
  4125. } else if (skey == UNIT_ATTENTION) {
  4126. notDone++; /* repeat */
  4127. } else if ((skey == NOT_READY) &&
  4128. (asc == 0x04)&&(ascq == 0x01)) {
  4129. /* wait then repeat */
  4130. mdelay (2000);
  4131. notDone++;
  4132. } else {
  4133. /* All other errors are fatal.
  4134. */
  4135. ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
  4136. ioc->name));
  4137. goto target_done;
  4138. }
  4139. } else {
  4140. /* All other errors are fatal
  4141. */
  4142. goto target_done;
  4143. }
  4144. }
  4145. }
  4146. if (iocmd.flags & MPT_ICFLAG_ECHO)
  4147. echoBufSize = bufsize;
  4148. else
  4149. dataBufSize = bufsize;
  4150. }
  4151. sz = 0;
  4152. iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
  4153. /* Use echo buffers if possible,
  4154. * Exit if both buffers are 0.
  4155. */
  4156. if (echoBufSize > 0) {
  4157. iocmd.flags |= MPT_ICFLAG_ECHO;
  4158. if (dataBufSize > 0)
  4159. bufsize = min(echoBufSize, dataBufSize);
  4160. else
  4161. bufsize = echoBufSize;
  4162. } else if (dataBufSize == 0)
  4163. goto target_done;
  4164. ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
  4165. (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
  4166. /* Data buffers for write-read-compare test max 1K.
  4167. */
  4168. sz = min(bufsize, 1024);
  4169. /* --- loop ----
  4170. * On first pass, always issue a reserve.
  4171. * On additional loops, only if a reset has occurred.
  4172. * iocmd.flags indicates if echo or regular buffer
  4173. */
  4174. for (patt = 0; patt < 4; patt++) {
  4175. ddvprintk(("Pattern %d\n", patt));
  4176. if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
  4177. iocmd.cmd = TEST_UNIT_READY;
  4178. iocmd.data_dma = -1;
  4179. iocmd.data = NULL;
  4180. iocmd.size = 0;
  4181. if (mptscsih_do_cmd(hd, &iocmd) < 0)
  4182. goto target_done;
  4183. iocmd.cmd = RELEASE;
  4184. iocmd.data_dma = -1;
  4185. iocmd.data = NULL;
  4186. iocmd.size = 0;
  4187. if (mptscsih_do_cmd(hd, &iocmd) < 0)
  4188. goto target_done;
  4189. else if (hd->pLocal == NULL)
  4190. goto target_done;
  4191. else {
  4192. rc = hd->pLocal->completion;
  4193. ddvprintk(("Release rc %d\n", rc));
  4194. if (rc == MPT_SCANDV_GOOD)
  4195. iocmd.flags &= ~MPT_ICFLAG_RESERVED;
  4196. else
  4197. goto target_done;
  4198. }
  4199. iocmd.flags &= ~MPT_ICFLAG_RESERVED;
  4200. }
  4201. iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
  4202. if (iocmd.flags & MPT_ICFLAG_EBOS)
  4203. goto skip_Reserve;
  4204. repeat = 5;
  4205. while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
  4206. iocmd.cmd = RESERVE;
  4207. iocmd.data_dma = -1;
  4208. iocmd.data = NULL;
  4209. iocmd.size = 0;
  4210. if (mptscsih_do_cmd(hd, &iocmd) < 0)
  4211. goto target_done;
  4212. else if (hd->pLocal == NULL)
  4213. goto target_done;
  4214. else {
  4215. rc = hd->pLocal->completion;
  4216. if (rc == MPT_SCANDV_GOOD) {
  4217. iocmd.flags |= MPT_ICFLAG_RESERVED;
  4218. } else if (rc == MPT_SCANDV_SENSE) {
  4219. /* Wait if coming ready
  4220. */
  4221. u8 skey = hd->pLocal->sense[2] & 0x0F;
  4222. u8 asc = hd->pLocal->sense[12];
  4223. u8 ascq = hd->pLocal->sense[13];
  4224. ddvprintk((MYIOC_s_INFO_FMT
  4225. "DV: Reserve Failed: ", ioc->name));
  4226. ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
  4227. skey, asc, ascq));
  4228. if ((skey == NOT_READY) && (asc == 0x04)&&
  4229. (ascq == 0x01)) {
  4230. /* wait then repeat */
  4231. mdelay (2000);
  4232. notDone++;
  4233. } else {
  4234. ddvprintk((MYIOC_s_INFO_FMT
  4235. "DV: Reserved Failed.", ioc->name));
  4236. goto target_done;
  4237. }
  4238. } else {
  4239. ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
  4240. ioc->name));
  4241. goto target_done;
  4242. }
  4243. }
  4244. }
  4245. skip_Reserve:
  4246. mptscsih_fillbuf(pbuf1, sz, patt, 1);
  4247. iocmd.cmd = WRITE_BUFFER;
  4248. iocmd.data_dma = buf1_dma;
  4249. iocmd.data = pbuf1;
  4250. iocmd.size = sz;
  4251. if (mptscsih_do_cmd(hd, &iocmd) < 0)
  4252. goto target_done;
  4253. else if (hd->pLocal == NULL)
  4254. goto target_done;
  4255. else {
  4256. rc = hd->pLocal->completion;
  4257. if (rc == MPT_SCANDV_GOOD)
  4258. ; /* Issue read buffer */
  4259. else if (rc == MPT_SCANDV_DID_RESET) {
  4260. /* If using echo buffers, reset to data buffers.
  4261. * Else do Fallback and restart
  4262. * this test (re-issue reserve
  4263. * because of bus reset).
  4264. */
  4265. if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
  4266. iocmd.flags &= ~MPT_ICFLAG_ECHO;
  4267. } else {
  4268. dv.cmd = MPT_FALLBACK;
  4269. mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
  4270. if (mpt_config(hd->ioc, &cfg) != 0)
  4271. goto target_done;
  4272. if ((!dv.now.width) && (!dv.now.offset))
  4273. goto target_done;
  4274. }
  4275. iocmd.flags |= MPT_ICFLAG_DID_RESET;
  4276. patt = -1;
  4277. continue;
  4278. } else if (rc == MPT_SCANDV_SENSE) {
  4279. /* Restart data test if UA, else quit.
  4280. */
  4281. u8 skey = hd->pLocal->sense[2] & 0x0F;
  4282. ddvprintk((MYIOC_s_INFO_FMT
  4283. "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
  4284. hd->pLocal->sense[12], hd->pLocal->sense[13]));
  4285. if (skey == UNIT_ATTENTION) {
  4286. patt = -1;
  4287. continue;
  4288. } else if (skey == ILLEGAL_REQUEST) {
  4289. if (iocmd.flags & MPT_ICFLAG_ECHO) {
  4290. if (dataBufSize >= bufsize) {
  4291. iocmd.flags &= ~MPT_ICFLAG_ECHO;
  4292. patt = -1;
  4293. continue;
  4294. }
  4295. }
  4296. goto target_done;
  4297. }
  4298. else
  4299. goto target_done;
  4300. } else {
  4301. /* fatal error */
  4302. goto target_done;
  4303. }
  4304. }
  4305. iocmd.cmd = READ_BUFFER;
  4306. iocmd.data_dma = buf2_dma;
  4307. iocmd.data = pbuf2;
  4308. iocmd.size = sz;
  4309. if (mptscsih_do_cmd(hd, &iocmd) < 0)
  4310. goto target_done;
  4311. else if (hd->pLocal == NULL)
  4312. goto target_done;
  4313. else {
  4314. rc = hd->pLocal->completion;
  4315. if (rc == MPT_SCANDV_GOOD) {
  4316. /* If buffers compare,
  4317. * go to next pattern,
  4318. * else, do a fallback and restart
  4319. * data transfer test.
  4320. */
  4321. if (memcmp (pbuf1, pbuf2, sz) == 0) {
  4322. ; /* goto next pattern */
  4323. } else {
  4324. /* Miscompare with Echo buffer, go to data buffer,
  4325. * if that buffer exists.
  4326. * Miscompare with Data buffer, check first 4 bytes,
  4327. * some devices return capacity. Exit in this case.
  4328. */
  4329. if (iocmd.flags & MPT_ICFLAG_ECHO) {
  4330. if (dataBufSize >= bufsize)
  4331. iocmd.flags &= ~MPT_ICFLAG_ECHO;
  4332. else
  4333. goto target_done;
  4334. } else {
  4335. if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
  4336. /* Argh. Device returning wrong data.
  4337. * Quit DV for this device.
  4338. */
  4339. goto target_done;
  4340. }
  4341. /* Had an actual miscompare. Slow down.*/
  4342. dv.cmd = MPT_FALLBACK;
  4343. mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
  4344. if (mpt_config(hd->ioc, &cfg) != 0)
  4345. goto target_done;
  4346. if ((!dv.now.width) && (!dv.now.offset))
  4347. goto target_done;
  4348. }
  4349. patt = -1;
  4350. continue;
  4351. }
  4352. } else if (rc == MPT_SCANDV_DID_RESET) {
  4353. /* Do Fallback and restart
  4354. * this test (re-issue reserve
  4355. * because of bus reset).
  4356. */
  4357. dv.cmd = MPT_FALLBACK;
  4358. mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
  4359. if (mpt_config(hd->ioc, &cfg) != 0)
  4360. goto target_done;
  4361. if ((!dv.now.width) && (!dv.now.offset))
  4362. goto target_done;
  4363. iocmd.flags |= MPT_ICFLAG_DID_RESET;
  4364. patt = -1;
  4365. continue;
  4366. } else if (rc == MPT_SCANDV_SENSE) {
  4367. /* Restart data test if UA, else quit.
  4368. */
  4369. u8 skey = hd->pLocal->sense[2] & 0x0F;
  4370. ddvprintk((MYIOC_s_INFO_FMT
  4371. "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
  4372. hd->pLocal->sense[12], hd->pLocal->sense[13]));
  4373. if (skey == UNIT_ATTENTION) {
  4374. patt = -1;
  4375. continue;
  4376. }
  4377. else
  4378. goto target_done;
  4379. } else {
  4380. /* fatal error */
  4381. goto target_done;
  4382. }
  4383. }
  4384. } /* --- end of patt loop ---- */
  4385. target_done:
  4386. if (iocmd.flags & MPT_ICFLAG_RESERVED) {
  4387. iocmd.cmd = RELEASE;
  4388. iocmd.data_dma = -1;
  4389. iocmd.data = NULL;
  4390. iocmd.size = 0;
  4391. if (mptscsih_do_cmd(hd, &iocmd) < 0)
  4392. printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
  4393. ioc->name, id);
  4394. else if (hd->pLocal) {
  4395. if (hd->pLocal->completion == MPT_SCANDV_GOOD)
  4396. iocmd.flags &= ~MPT_ICFLAG_RESERVED;
  4397. } else {
  4398. printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
  4399. ioc->name, id);
  4400. }
  4401. }
  4402. /* Set if cfg1_dma_addr contents is valid
  4403. */
  4404. if ((cfg.cfghdr.hdr != NULL) && (retcode == 0)){
  4405. /* If disk, not U320, disable QAS
  4406. */
  4407. if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
  4408. hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
  4409. ddvprintk((MYIOC_s_NOTE_FMT
  4410. "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
  4411. }
  4412. dv.cmd = MPT_SAVE;
  4413. mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
  4414. /* Double writes to SDP1 can cause problems,
  4415. * skip save of the final negotiated settings to
  4416. * SCSI device page 1.
  4417. *
  4418. cfg.cfghdr.hdr = &header1;
  4419. cfg.physAddr = cfg1_dma_addr;
  4420. cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
  4421. cfg.dir = 1;
  4422. mpt_config(hd->ioc, &cfg);
  4423. */
  4424. }
  4425. /* If this is a RAID Passthrough, enable internal IOs
  4426. */
  4427. if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
  4428. if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
  4429. ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
  4430. }
  4431. /* Done with the DV scan of the current target
  4432. */
  4433. if (pDvBuf)
  4434. pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
  4435. ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n",
  4436. ioc->name, id));
  4437. return retcode;
  4438. }
  4439. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  4440. /* mptscsih_dv_parms - perform a variety of operations on the
  4441. * parameters used for negotiation.
  4442. * @hd: Pointer to a SCSI host.
  4443. * @dv: Pointer to a structure that contains the maximum and current
  4444. * negotiated parameters.
  4445. */
  4446. static void
  4447. mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
  4448. {
  4449. VirtTarget *vtarget;
  4450. SCSIDevicePage0_t *pPage0;
  4451. SCSIDevicePage1_t *pPage1;
  4452. int val = 0, data, configuration;
  4453. u8 width = 0;
  4454. u8 offset = 0;
  4455. u8 factor = 0;
  4456. u8 negoFlags = 0;
  4457. u8 cmd = dv->cmd;
  4458. u8 id = dv->id;
  4459. switch (cmd) {
  4460. case MPT_GET_NVRAM_VALS:
  4461. ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
  4462. hd->ioc->name));
  4463. /* Get the NVRAM values and save in tmax
  4464. * If not an LVD bus, the adapter minSyncFactor has been
  4465. * already throttled back.
  4466. */
  4467. negoFlags = hd->ioc->spi_data.noQas;
  4468. if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume) {
  4469. width = vtarget->maxWidth;
  4470. offset = vtarget->maxOffset;
  4471. factor = vtarget->minSyncFactor;
  4472. negoFlags |= vtarget->negoFlags;
  4473. } else {
  4474. if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
  4475. data = hd->ioc->spi_data.nvram[id];
  4476. width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
  4477. if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
  4478. factor = MPT_ASYNC;
  4479. else {
  4480. factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
  4481. if ((factor == 0) || (factor == MPT_ASYNC)){
  4482. factor = MPT_ASYNC;
  4483. offset = 0;
  4484. }
  4485. }
  4486. } else {
  4487. width = MPT_NARROW;
  4488. offset = 0;
  4489. factor = MPT_ASYNC;
  4490. }
  4491. /* Set the negotiation flags */
  4492. if (!width)
  4493. negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
  4494. if (!offset)
  4495. negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
  4496. }
  4497. /* limit by adapter capabilities */
  4498. width = min(width, hd->ioc->spi_data.maxBusWidth);
  4499. offset = min(offset, hd->ioc->spi_data.maxSyncOffset);
  4500. factor = max(factor, hd->ioc->spi_data.minSyncFactor);
  4501. /* Check Consistency */
  4502. if (offset && (factor < MPT_ULTRA2) && !width)
  4503. factor = MPT_ULTRA2;
  4504. dv->max.width = width;
  4505. dv->max.offset = offset;
  4506. dv->max.factor = factor;
  4507. dv->max.flags = negoFlags;
  4508. ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
  4509. id, width, factor, offset, negoFlags));
  4510. break;
  4511. case MPT_UPDATE_MAX:
  4512. ddvprintk((MYIOC_s_NOTE_FMT
  4513. "Updating with SDP0 Data: ", hd->ioc->name));
  4514. /* Update tmax values with those from Device Page 0.*/
  4515. pPage0 = (SCSIDevicePage0_t *) pPage;
  4516. if (pPage0) {
  4517. val = le32_to_cpu(pPage0->NegotiatedParameters);
  4518. dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
  4519. dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
  4520. dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
  4521. }
  4522. dv->now.width = dv->max.width;
  4523. dv->now.offset = dv->max.offset;
  4524. dv->now.factor = dv->max.factor;
  4525. ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
  4526. id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
  4527. break;
  4528. case MPT_SET_MAX:
  4529. ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
  4530. hd->ioc->name));
  4531. /* Set current to the max values. Update the config page.*/
  4532. dv->now.width = dv->max.width;
  4533. dv->now.offset = dv->max.offset;
  4534. dv->now.factor = dv->max.factor;
  4535. dv->now.flags = dv->max.flags;
  4536. pPage1 = (SCSIDevicePage1_t *)pPage;
  4537. if (pPage1) {
  4538. mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
  4539. dv->now.offset, &val, &configuration, dv->now.flags);
  4540. dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
  4541. id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
  4542. pPage1->RequestedParameters = cpu_to_le32(val);
  4543. pPage1->Reserved = 0;
  4544. pPage1->Configuration = cpu_to_le32(configuration);
  4545. }
  4546. ddvprintk(("id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x configuration=%x\n",
  4547. id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
  4548. break;
  4549. case MPT_SET_MIN:
  4550. ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
  4551. hd->ioc->name));
  4552. /* Set page to asynchronous and narrow
  4553. * Do not update now, breaks fallback routine. */
  4554. width = MPT_NARROW;
  4555. offset = 0;
  4556. factor = MPT_ASYNC;
  4557. negoFlags = dv->max.flags;
  4558. pPage1 = (SCSIDevicePage1_t *)pPage;
  4559. if (pPage1) {
  4560. mptscsih_setDevicePage1Flags (width, factor,
  4561. offset, &val, &configuration, negoFlags);
  4562. dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
  4563. id, width, factor, offset, negoFlags, val, configuration));
  4564. pPage1->RequestedParameters = cpu_to_le32(val);
  4565. pPage1->Reserved = 0;
  4566. pPage1->Configuration = cpu_to_le32(configuration);
  4567. }
  4568. ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
  4569. id, width, factor, offset, val, configuration, negoFlags));
  4570. break;
  4571. case MPT_FALLBACK:
  4572. ddvprintk((MYIOC_s_NOTE_FMT
  4573. "Fallback: Start: offset %d, factor %x, width %d \n",
  4574. hd->ioc->name, dv->now.offset,
  4575. dv->now.factor, dv->now.width));
  4576. width = dv->now.width;
  4577. offset = dv->now.offset;
  4578. factor = dv->now.factor;
  4579. if ((offset) && (dv->max.width)) {
  4580. if (factor < MPT_ULTRA160)
  4581. factor = MPT_ULTRA160;
  4582. else if (factor < MPT_ULTRA2) {
  4583. factor = MPT_ULTRA2;
  4584. width = MPT_WIDE;
  4585. } else if ((factor == MPT_ULTRA2) && width) {
  4586. factor = MPT_ULTRA2;
  4587. width = MPT_NARROW;
  4588. } else if (factor < MPT_ULTRA) {
  4589. factor = MPT_ULTRA;
  4590. width = MPT_WIDE;
  4591. } else if ((factor == MPT_ULTRA) && width) {
  4592. width = MPT_NARROW;
  4593. } else if (factor < MPT_FAST) {
  4594. factor = MPT_FAST;
  4595. width = MPT_WIDE;
  4596. } else if ((factor == MPT_FAST) && width) {
  4597. factor = MPT_FAST;
  4598. width = MPT_NARROW;
  4599. } else if (factor < MPT_SCSI) {
  4600. factor = MPT_SCSI;
  4601. width = MPT_WIDE;
  4602. } else if ((factor == MPT_SCSI) && width) {
  4603. factor = MPT_SCSI;
  4604. width = MPT_NARROW;
  4605. } else {
  4606. factor = MPT_ASYNC;
  4607. offset = 0;
  4608. }
  4609. } else if (offset) {
  4610. width = MPT_NARROW;
  4611. if (factor < MPT_ULTRA)
  4612. factor = MPT_ULTRA;
  4613. else if (factor < MPT_FAST)
  4614. factor = MPT_FAST;
  4615. else if (factor < MPT_SCSI)
  4616. factor = MPT_SCSI;
  4617. else {
  4618. factor = MPT_ASYNC;
  4619. offset = 0;
  4620. }
  4621. } else {
  4622. width = MPT_NARROW;
  4623. factor = MPT_ASYNC;
  4624. }
  4625. dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
  4626. dv->max.flags &= ~MPT_TAPE_NEGO_IDP;
  4627. dv->now.width = width;
  4628. dv->now.offset = offset;
  4629. dv->now.factor = factor;
  4630. dv->now.flags = dv->max.flags;
  4631. pPage1 = (SCSIDevicePage1_t *)pPage;
  4632. if (pPage1) {
  4633. mptscsih_setDevicePage1Flags (width, factor, offset, &val,
  4634. &configuration, dv->now.flags);
  4635. dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x negoFlags=%x request=%x config=%x\n",
  4636. id, width, offset, factor, dv->now.flags, val, configuration));
  4637. pPage1->RequestedParameters = cpu_to_le32(val);
  4638. pPage1->Reserved = 0;
  4639. pPage1->Configuration = cpu_to_le32(configuration);
  4640. }
  4641. ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
  4642. id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
  4643. break;
  4644. case MPT_SAVE:
  4645. ddvprintk((MYIOC_s_NOTE_FMT
  4646. "Saving to Target structure: ", hd->ioc->name));
  4647. ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
  4648. id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
  4649. /* Save these values to target structures
  4650. * or overwrite nvram (phys disks only).
  4651. */
  4652. if ((hd->Targets)&&((vtarget = hd->Targets[(int)id]) != NULL) && !vtarget->raidVolume ) {
  4653. vtarget->maxWidth = dv->now.width;
  4654. vtarget->maxOffset = dv->now.offset;
  4655. vtarget->minSyncFactor = dv->now.factor;
  4656. vtarget->negoFlags = dv->now.flags;
  4657. } else {
  4658. /* Preserv all flags, use
  4659. * read-modify-write algorithm
  4660. */
  4661. if (hd->ioc->spi_data.nvram) {
  4662. data = hd->ioc->spi_data.nvram[id];
  4663. if (dv->now.width)
  4664. data &= ~MPT_NVRAM_WIDE_DISABLE;
  4665. else
  4666. data |= MPT_NVRAM_WIDE_DISABLE;
  4667. if (!dv->now.offset)
  4668. factor = MPT_ASYNC;
  4669. data &= ~MPT_NVRAM_SYNC_MASK;
  4670. data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
  4671. hd->ioc->spi_data.nvram[id] = data;
  4672. }
  4673. }
  4674. break;
  4675. }
  4676. }
  4677. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  4678. /* mptscsih_fillbuf - fill a buffer with a special data pattern
  4679. * cleanup. For bus scan only.
  4680. *
  4681. * @buffer: Pointer to data buffer to be filled.
  4682. * @size: Number of bytes to fill
  4683. * @index: Pattern index
  4684. * @width: bus width, 0 (8 bits) or 1 (16 bits)
  4685. */
  4686. static void
  4687. mptscsih_fillbuf(char *buffer, int size, int index, int width)
  4688. {
  4689. char *ptr = buffer;
  4690. int ii;
  4691. char byte;
  4692. short val;
  4693. switch (index) {
  4694. case 0:
  4695. if (width) {
  4696. /* Pattern: 0000 FFFF 0000 FFFF
  4697. */
  4698. for (ii=0; ii < size; ii++, ptr++) {
  4699. if (ii & 0x02)
  4700. *ptr = 0xFF;
  4701. else
  4702. *ptr = 0x00;
  4703. }
  4704. } else {
  4705. /* Pattern: 00 FF 00 FF
  4706. */
  4707. for (ii=0; ii < size; ii++, ptr++) {
  4708. if (ii & 0x01)
  4709. *ptr = 0xFF;
  4710. else
  4711. *ptr = 0x00;
  4712. }
  4713. }
  4714. break;
  4715. case 1:
  4716. if (width) {
  4717. /* Pattern: 5555 AAAA 5555 AAAA 5555
  4718. */
  4719. for (ii=0; ii < size; ii++, ptr++) {
  4720. if (ii & 0x02)
  4721. *ptr = 0xAA;
  4722. else
  4723. *ptr = 0x55;
  4724. }
  4725. } else {
  4726. /* Pattern: 55 AA 55 AA 55
  4727. */
  4728. for (ii=0; ii < size; ii++, ptr++) {
  4729. if (ii & 0x01)
  4730. *ptr = 0xAA;
  4731. else
  4732. *ptr = 0x55;
  4733. }
  4734. }
  4735. break;
  4736. case 2:
  4737. /* Pattern: 00 01 02 03 04 05
  4738. * ... FE FF 00 01..
  4739. */
  4740. for (ii=0; ii < size; ii++, ptr++)
  4741. *ptr = (char) ii;
  4742. break;
  4743. case 3:
  4744. if (width) {
  4745. /* Wide Pattern: FFFE 0001 FFFD 0002
  4746. * ... 4000 DFFF 8000 EFFF
  4747. */
  4748. byte = 0;
  4749. for (ii=0; ii < size/2; ii++) {
  4750. /* Create the base pattern
  4751. */
  4752. val = (1 << byte);
  4753. /* every 64 (0x40) bytes flip the pattern
  4754. * since we fill 2 bytes / iteration,
  4755. * test for ii = 0x20
  4756. */
  4757. if (ii & 0x20)
  4758. val = ~(val);
  4759. if (ii & 0x01) {
  4760. *ptr = (char)( (val & 0xFF00) >> 8);
  4761. ptr++;
  4762. *ptr = (char)(val & 0xFF);
  4763. byte++;
  4764. byte &= 0x0F;
  4765. } else {
  4766. val = ~val;
  4767. *ptr = (char)( (val & 0xFF00) >> 8);
  4768. ptr++;
  4769. *ptr = (char)(val & 0xFF);
  4770. }
  4771. ptr++;
  4772. }
  4773. } else {
  4774. /* Narrow Pattern: FE 01 FD 02 FB 04
  4775. * .. 7F 80 01 FE 02 FD ... 80 7F
  4776. */
  4777. byte = 0;
  4778. for (ii=0; ii < size; ii++, ptr++) {
  4779. /* Base pattern - first 32 bytes
  4780. */
  4781. if (ii & 0x01) {
  4782. *ptr = (1 << byte);
  4783. byte++;
  4784. byte &= 0x07;
  4785. } else {
  4786. *ptr = (char) (~(1 << byte));
  4787. }
  4788. /* Flip the pattern every 32 bytes
  4789. */
  4790. if (ii & 0x20)
  4791. *ptr = ~(*ptr);
  4792. }
  4793. }
  4794. break;
  4795. }
  4796. }
  4797. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
  4798. /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
  4799. * Else set the NEED_DV flag after Read Capacity Issued (disks)
  4800. * or Mode Sense (cdroms).
  4801. *
  4802. * Tapes, initTarget will set this flag on completion of Inquiry command.
  4803. * Called only if DV_NOT_DONE flag is set
  4804. */
  4805. static void
  4806. mptscsih_set_dvflags(MPT_SCSI_HOST *hd, struct scsi_cmnd *sc)
  4807. {
  4808. MPT_ADAPTER *ioc = hd->ioc;
  4809. u8 cmd;
  4810. SpiCfgData *pSpi;
  4811. ddvtprintk((MYIOC_s_NOTE_FMT
  4812. " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
  4813. hd->ioc->name, sc->device->id, sc->device->lun , hd->negoNvram, sc->cmnd[0]));
  4814. if ((sc->device->lun != 0) || (hd->negoNvram != 0))
  4815. return;
  4816. cmd = sc->cmnd[0];
  4817. if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
  4818. pSpi = &ioc->spi_data;
  4819. if ((ioc->raid_data.isRaid & (1 << sc->device->id)) && ioc->raid_data.pIocPg3) {
  4820. /* Set NEED_DV for all hidden disks
  4821. */
  4822. Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
  4823. int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
  4824. while (numPDisk) {
  4825. pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
  4826. ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
  4827. pPDisk++;
  4828. numPDisk--;
  4829. }
  4830. }
  4831. pSpi->dvStatus[sc->device->id] |= MPT_SCSICFG_NEED_DV;
  4832. ddvtprintk(("NEED_DV set for visible disk id %d\n", sc->device->id));
  4833. }
  4834. }
  4835. /* mptscsih_raid_set_dv_flags()
  4836. *
  4837. * New or replaced disk. Set DV flag and schedule DV.
  4838. */
  4839. static void
  4840. mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id)
  4841. {
  4842. MPT_ADAPTER *ioc = hd->ioc;
  4843. SpiCfgData *pSpi = &ioc->spi_data;
  4844. Ioc3PhysDisk_t *pPDisk;
  4845. int numPDisk;
  4846. if (hd->negoNvram != 0)
  4847. return;
  4848. ddvtprintk(("DV requested for phys disk id %d\n", id));
  4849. if (ioc->raid_data.pIocPg3) {
  4850. pPDisk = ioc->raid_data.pIocPg3->PhysDisk;
  4851. numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks;
  4852. while (numPDisk) {
  4853. if (id == pPDisk->PhysDiskNum) {
  4854. pSpi->dvStatus[pPDisk->PhysDiskID] =
  4855. (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
  4856. pSpi->forceDv = MPT_SCSICFG_NEED_DV;
  4857. ddvtprintk(("NEED_DV set for phys disk id %d\n",
  4858. pPDisk->PhysDiskID));
  4859. break;
  4860. }
  4861. pPDisk++;
  4862. numPDisk--;
  4863. }
  4864. if (numPDisk == 0) {
  4865. /* The physical disk that needs DV was not found
  4866. * in the stored IOC Page 3. The driver must reload
  4867. * this page. DV routine will set the NEED_DV flag for
  4868. * all phys disks that have DV_NOT_DONE set.
  4869. */
  4870. pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
  4871. ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id));
  4872. }
  4873. }
  4874. }
  4875. #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
  4876. EXPORT_SYMBOL(mptscsih_remove);
  4877. EXPORT_SYMBOL(mptscsih_shutdown);
  4878. #ifdef CONFIG_PM
  4879. EXPORT_SYMBOL(mptscsih_suspend);
  4880. EXPORT_SYMBOL(mptscsih_resume);
  4881. #endif
  4882. EXPORT_SYMBOL(mptscsih_proc_info);
  4883. EXPORT_SYMBOL(mptscsih_info);
  4884. EXPORT_SYMBOL(mptscsih_qcmd);
  4885. EXPORT_SYMBOL(mptscsih_target_alloc);
  4886. EXPORT_SYMBOL(mptscsih_slave_alloc);
  4887. EXPORT_SYMBOL(mptscsih_target_destroy);
  4888. EXPORT_SYMBOL(mptscsih_slave_destroy);
  4889. EXPORT_SYMBOL(mptscsih_slave_configure);
  4890. EXPORT_SYMBOL(mptscsih_abort);
  4891. EXPORT_SYMBOL(mptscsih_dev_reset);
  4892. EXPORT_SYMBOL(mptscsih_bus_reset);
  4893. EXPORT_SYMBOL(mptscsih_host_reset);
  4894. EXPORT_SYMBOL(mptscsih_bios_param);
  4895. EXPORT_SYMBOL(mptscsih_io_done);
  4896. EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
  4897. EXPORT_SYMBOL(mptscsih_scandv_complete);
  4898. EXPORT_SYMBOL(mptscsih_event_process);
  4899. EXPORT_SYMBOL(mptscsih_ioc_reset);
  4900. EXPORT_SYMBOL(mptscsih_change_queue_depth);
  4901. EXPORT_SYMBOL(mptscsih_timer_expired);
  4902. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/