modem_sdio.c 163 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115
  1. /*
  2. *drivers/mmc/card/modem_sdio.c
  3. *
  4. *VIA CBP SDIO driver for Linux
  5. *
  6. *Copyright (C) 2009 VIA TELECOM Corporation, Inc.
  7. *Author: VIA TELECOM Corporation, Inc.
  8. *
  9. *This package is free software; you can redistribute it and/or modify
  10. *it under the terms of the GNU General Public License version 2 as
  11. *published by the Free Software Foundation.
  12. *
  13. *THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14. *IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15. *WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16. */
  17. #include <linux/module.h>
  18. #include <linux/mod_devicetable.h>
  19. #include <linux/mmc/core.h>
  20. #include <linux/mmc/card.h>
  21. #include <linux/mmc/sdio.h>
  22. #include <linux/mmc/sdio_func.h>
  23. #include <linux/mmc/sdio_ids.h>
  24. #include <linux/platform_device.h>
  25. #include <linux/irq.h>
  26. #include <linux/circ_buf.h>
  27. #include <linux/kfifo.h>
  28. #include <linux/slab.h>
  29. #include <linux/fs.h>
  30. #include <linux/delay.h>
  31. #include <linux/timer.h>
  32. #include <linux/init.h>
  33. #include <linux/kernel.h>
  34. #include <linux/sched.h>
  35. #include <linux/mutex.h>
  36. #include <linux/mmc/host.h>
  37. #include <linux/gpio.h>
  38. #include <linux/wait.h>
  39. #include <linux/workqueue.h>
  40. #include <linux/version.h>
  41. #include "viatel_rawbulk.h"
  42. #include "modem_sdio.h"
  43. #include "c2k_hw.h"
  44. #ifdef CONFIG_MTK_AEE_FEATURE
  45. #include <mt-plat/aee.h>
  46. #else
  47. #define DB_OPT_DEFAULT (0) /*Dummy macro define to avoid build error */
  48. #define DB_OPT_FTRACE (0) /*Dummy macro define to avoid build error */
  49. #endif
  50. #if ENABLE_CHAR_DEV
  51. #include <linux/cdev.h>
  52. #include <linux/device.h>
  53. #include <linux/fs.h>
  54. #include <linux/uaccess.h>
  55. #include <linux/poll.h>
  56. #else
  57. #include <linux/tty.h>
  58. #include <linux/tty_flip.h>
  59. #endif
  60. #if ENABLE_CCMNI
  61. #include <linux/skbuff.h>
  62. /*#include "c2k_ccmni_ccci_intf.h"*/
  63. #include "ccmni.h"
  64. #endif
  65. static int sdio_tx_cnt;
  66. static int sdio_rx_cnt;
  67. #define FIFO_SIZE (8*PAGE_SIZE) /*transmit fifo size for each tty port */
  68. #define SDIO_WAKEUP_CHARS (8*256) /*when data in transmit buffer less than this, ask for more from tty */
  69. #ifdef CONFIG_EVDO_DT_VIA_SUPPORT
  70. #define TRANSMIT_SHIFT (10)
  71. #else
  72. #define TRANSMIT_SHIFT (11)
  73. #endif
  74. #define TRANSMIT_BUFFER_SIZE (1UL << TRANSMIT_SHIFT)
  75. #define TRANSMIT_MAX_SIZE ((1UL << TRANSMIT_SHIFT) - sizeof(struct sdio_msg_head))
  76. #define RECORD_DUMP_MAX (20)
  77. #define PADDING_BY_BLOCK_SIZE (0)
  78. #if USE_CCIF_INTR
  79. #define RX_DONE_CH (1)
  80. #define TX_DATA_CH (0)
  81. #endif
  82. static struct tty_driver *modem_sdio_tty_driver;
  83. int sdio_log_level = LOG_ERR;
  84. struct sdio_modem *c2k_modem = NULL;
  85. static unsigned int dtr_value;
  86. static unsigned int dcd_state;
  87. static char *type_str[] = {[md_type_invalid] = "invalid",
  88. [modem_2g] = "2g",
  89. [modem_3g] = "3g",
  90. [modem_wg] = "wg",
  91. [modem_tg] = "tg",
  92. [modem_lwg] = "lwg",
  93. [modem_ltg] = "ltg",
  94. [modem_sglte] = "sglte"
  95. };
  96. static char *product_str[] = {[INVALID_VARSION] = INVALID_STR,
  97. [DEBUG_VERSION] = DEBUG_STR,
  98. [RELEASE_VERSION] = RELEASE_STR
  99. };
  100. char c2k_img_info_str[256];
  101. #if ENABLE_CCMNI
  102. /************************ccmni struct define***********************/
  103. #define CCMNI_INTF_COUNT (3)
  104. #define SDIO_MD_ID (2)
  105. #define CCMNI_CH_ID DATA_CH_ID
  106. /************************ccmni struct define***********************/
  107. int sdio_modem_get_ccmni_ch(int md_id, int ccmni_idx, struct ccmni_ch *channel)
  108. {
  109. int ret = 0;
  110. if ((ccmni_idx >= 0) && (ccmni_idx < CCMNI_INTF_COUNT)) {
  111. channel->rx = ccmni_idx;
  112. channel->rx_ack = 0xFF;
  113. channel->tx = ccmni_idx;
  114. channel->tx_ack = 0xFF;
  115. } else {
  116. pr_debug("[ccci%d/net] invalid ccmni index=%d\n", md_id,
  117. ccmni_idx);
  118. ret = -1;
  119. }
  120. return ret;
  121. }
  122. struct ccmni_ccci_ops sdio_ccmni_ops = {
  123. .ccmni_ver = CCMNI_DRV_V0, /*CCMNI_DRV_VER */
  124. .ccmni_num = CCMNI_INTF_COUNT,
  125. .name = "cc3mni", /*"ccmni" or "cc2mni" or "ccemni" */
  126. #if defined CONFIG_MTK_IRAT_SUPPORT
  127. #if defined CONFIG_MTK_C2K_SLOT2_SUPPORT
  128. .md_ability = MODEM_CAP_CCMNI_IRAT | MODEM_CAP_TXBUSY_STOP | MODEM_CAP_WORLD_PHONE,
  129. #else
  130. .md_ability = MODEM_CAP_CCMNI_IRAT | MODEM_CAP_TXBUSY_STOP,
  131. #endif
  132. .irat_md_id = MD_SYS1,
  133. #else
  134. .md_ability = MODEM_CAP_TXBUSY_STOP,
  135. .irat_md_id = -1,
  136. #endif
  137. .napi_poll_weigh = 0,
  138. .send_pkt = sdio_modem_ccmni_send_pkt,
  139. .napi_poll = NULL,
  140. .get_ccmni_ch = sdio_modem_get_ccmni_ch,
  141. };
  142. #endif
  143. /*static unsigned int modem_remove = 1;*/
  144. /*static spinlock_t modem_remove_lock;*/
  145. /*#define TX_DONE_TRACE*/
  146. #ifdef TX_DONE_TRACE
  147. struct timer_list timer_wait_tx_done;
  148. static void wait_tx_done_timer(unsigned long data)
  149. {
  150. msdc_c2k_dump_int_register();
  151. mod_timer(&timer_wait_tx_done, jiffies + msecs_to_jiffies(1000));
  152. }
  153. #endif
  154. static inline int calc_payload_len(const struct sdio_msg_head *head,
  155. unsigned int *offset)
  156. {
  157. unsigned int len = 0;
  158. unsigned int payload_offset = 0;
  159. #if 0
  160. struct sdio_msg_head *head = NULL;
  161. if (buf) {
  162. head = (struct sdio_msg_head *)buf;
  163. len = (((head->tranHi & 0x0F) << 8) | (head->tranLow & 0xFF));
  164. }
  165. #else
  166. if (head) {
  167. payload_offset = ((head->tranHi & 0xC0) >> 6);
  168. if (payload_offset) {
  169. LOGPRT(LOG_DEBUG, "%s %d: payload_offset = %d.\n",
  170. __func__, __LINE__, payload_offset);
  171. }
  172. len = (((head->tranHi & 0x0F) << 8) | (head->tranLow & 0xFF));
  173. len -= payload_offset;
  174. }
  175. #endif
  176. if (offset)
  177. *offset = payload_offset;
  178. return len;
  179. }
  180. /**
  181. *sdio_tx_rx_printk - print sdio tx and rx data, when log level is LOG_NOTICE or larger
  182. *@buf: the point of data buffer
  183. *@type: print type, 0:rx 1:tx
  184. *
  185. *no return
  186. */
  187. static void sdio_tx_rx_printk(const void *buf, unsigned char type)
  188. {
  189. unsigned int count;
  190. const unsigned char *print_buf = (const unsigned char *)buf;
  191. const struct sdio_msg_head *head = NULL;
  192. /*int i; */
  193. /*return; */
  194. if (buf)
  195. head = (struct sdio_msg_head *)buf;
  196. count = calc_payload_len(head, NULL);
  197. if (type == 1)
  198. LOGPRT(LOG_INFO, "write %d to channel%d/[%d]>>",
  199. count, head->chanInfo, sdio_tx_cnt);
  200. else
  201. LOGPRT(LOG_INFO, "read %d from channel%d/[%d]<<",
  202. count, head->chanInfo, sdio_rx_cnt);
  203. /*if(count > RECORD_DUMP_MAX) */
  204. /*count = RECORD_DUMP_MAX; */
  205. LOGPRT
  206. (LOG_INFO, "%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x\n",
  207. *print_buf, *(print_buf + 1), *(print_buf + 2), *(print_buf + 3),
  208. *(print_buf + 4), *(print_buf + 5), *(print_buf + 6),
  209. *(print_buf + 7), *(print_buf + 8), *(print_buf + 9),
  210. *(print_buf + 10), *(print_buf + 11), *(print_buf + 12),
  211. *(print_buf + 13), *(print_buf + 14), *(print_buf + 15),
  212. *(print_buf + 16), *(print_buf + 17), *(print_buf + 18),
  213. *(print_buf + 19), *(print_buf + 20), *(print_buf + 21),
  214. *(print_buf + 22), *(print_buf + 23));
  215. /*
  216. for(i = 0; i < count + sizeof(struct sdio_msg_head); i++)
  217. {
  218. printk(KERN_CONT "%x-", *(print_buf+i));
  219. }
  220. printk(KERN_CONT "\n");
  221. */
  222. }
  223. #if 0
  224. static void sdio_rx_check(struct sdio_modem *modem, const void *buf)
  225. {
  226. unsigned int count;
  227. const unsigned char *print_buf = (const unsigned char *)buf;
  228. int i;
  229. const struct sdio_msg_head *head = NULL;
  230. if (buf)
  231. head = (struct sdio_msg_head *)buf;
  232. return;
  233. /*calc payload length */
  234. count = calc_payload_len(head, NULL);
  235. pr_debug("[MODEM SDIO] rx_check chan [%d], data_len [%d]\n",
  236. *(print_buf + 1), count);
  237. for (i = 0; i < count + sizeof(struct sdio_msg_head); i++) {
  238. if (i % 16 == 0)
  239. pr_debug("[MODEM SDIO] rx_check ");
  240. pr_debug("%02X-", *(print_buf + i));
  241. if ((i + 1) % 16 == 0)
  242. pr_debug("\n");
  243. }
  244. pr_debug("\n");
  245. }
  246. #endif
  247. static struct sdio_modem_port *sdio_modem_tty_port_get(unsigned index)
  248. {
  249. struct sdio_modem_port *port = NULL;
  250. /*unsigned long flags = 0; */
  251. if (index >= SDIO_TTY_NR)
  252. return NULL;
  253. if (c2k_modem)
  254. port = c2k_modem->port[index];
  255. return port;
  256. }
  257. static void sdio_modem_port_destroy(struct kref *kref)
  258. {
  259. struct sdio_modem_port *port =
  260. container_of(kref, struct sdio_modem_port, kref);
  261. int index;
  262. if (port) {
  263. index = port->index;
  264. LOGPRT(LOG_INFO, "%s %d: index = %d .\n", __func__, __LINE__,
  265. index);
  266. kfifo_free(&port->transmit_fifo);
  267. kfree(port);
  268. } else {
  269. LOGPRT(LOG_ERR, "%s %d: invalid port.\n", __func__, __LINE__);
  270. }
  271. }
  272. /*we just call kref_get in modem_tty_install once, so when port not exist any more, call this function to destroy it.*/
  273. static void sdio_modem_tty_port_put(struct sdio_modem_port *port)
  274. {
  275. if (port) {
  276. LOGPRT(LOG_INFO, "%s %d: port %d.\n", __func__, __LINE__,
  277. port->index);
  278. kref_put(&port->kref, sdio_modem_port_destroy);
  279. } else {
  280. LOGPRT(LOG_ERR, "%s %d: invalid port.\n", __func__, __LINE__);
  281. }
  282. }
  283. /*check if port is valid*/
  284. static int check_port(struct sdio_modem_port *port)
  285. {
  286. struct sdio_modem *modem = NULL;
  287. int ret = 0;
  288. if (!port) {
  289. LOGPRT(LOG_ERR, "%s port NULL\n", __func__);
  290. ret = -ENODEV;
  291. } else {
  292. modem = port->modem;
  293. if (!port->func) {
  294. LOGPRT(LOG_ERR, "%s %d: port%d func NULL\n", __func__,
  295. __LINE__, port->index);
  296. ret = -ENODEV;
  297. } else if (modem->status == MD_OFF) {
  298. LOGPRT(LOG_ERR, "%s %d: modem is off now.(%d)\n",
  299. __func__, __LINE__, port->index);
  300. ret = -ENODEV;
  301. }
  302. }
  303. /*WARN_ON(!port->port.count); */
  304. LOGPRT(LOG_INFO, "%s %d: check port OK.(%d)\n",
  305. __func__, __LINE__, port->index);
  306. return ret;
  307. }
  308. static void modem_sdio_write(struct sdio_modem *modem, int addr,
  309. void *buf, size_t len);
  310. /*CBP control message type */
  311. enum cbp_contrl_message_type {
  312. CHAN_ONOFF_MSG_ID = 0,
  313. MDM_STATUS_IND_MSG_ID,
  314. MDM_STATUS_QUERY_MSG_ID,
  315. CHAN_SWITCH_REQ_MSG_ID,
  316. CHAN_STATUS_QUERY_MSG_ID,
  317. FLOW_CONTROL_MSG_ID,
  318. CHAN_LOOPBACK_TST_MSG_ID,
  319. HEART_BEAT_MSG_ID,
  320. FORCE_ASSERT_MSG_ID,
  321. MESSAGE_COUNT,
  322. };
  323. enum {
  324. CHAN_OFF = 0,
  325. CHAN_ON,
  326. };
  327. enum {
  328. OPT_LOOPBACK_NON = 0, /*no operation, default 0 */
  329. OPT_LOOPBACK_OPEN = 1, /*open loopback test */
  330. OPT_LOOPBACK_CLOSE = 2, /*close loopback test */
  331. OPT_LOOPBACK_QUERY = 3, /*query loopback test */
  332. OPT_LOOPBACK_NUM
  333. };
  334. static int contruct_ctrl_chan_msg(struct sdio_modem_ctrl_port *ctrl_port,
  335. int msg, unsigned char chan_num,
  336. unsigned char opt)
  337. {
  338. if (unlikely(ctrl_port == NULL)) {
  339. LOGPRT(LOG_ERR, "%s %d: control channel is null.\n", __func__,
  340. __LINE__);
  341. return -EINVAL;
  342. }
  343. ctrl_port->chan_ctrl_msg.head.start_flag = MSG_START_FLAG;
  344. ctrl_port->chan_ctrl_msg.head.chanInfo = 0;
  345. ctrl_port->chan_ctrl_msg.head.tranHi = 0; /*High byte of the following payload length */
  346. ctrl_port->chan_ctrl_msg.head.tranLow = 4; /*Low byte of the following payload length */
  347. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  348. ctrl_port->chan_ctrl_msg.head.hw_head.len_hi =
  349. 0xFF & (sizeof(struct ctrl_port_msg) >> 8);
  350. ctrl_port->chan_ctrl_msg.head.hw_head.len_low =
  351. 0xFF & sizeof(struct ctrl_port_msg);
  352. #endif
  353. /*High byte of control message ID,for onoff request ID=CHAN_ONOFF_MSG_ID */
  354. ctrl_port->chan_ctrl_msg.id_hi = msg >> 8;
  355. /*Low byte of control message ID,for onoff request ID=CHAN_ONOFF_MSG_ID */
  356. ctrl_port->chan_ctrl_msg.id_low = msg;
  357. ctrl_port->chan_ctrl_msg.chan_num = chan_num; /*ChanNum ,same as ChanInfo */
  358. ctrl_port->chan_ctrl_msg.option = opt;
  359. return 0;
  360. }
  361. static unsigned char loop_back[12];
  362. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  363. static unsigned short hear_beat_counter;
  364. static void modem_heart_beat_poll_work(struct work_struct *work)
  365. {
  366. struct sdio_modem *modem =
  367. container_of(work, struct sdio_modem, poll_hb_work);
  368. struct sdio_modem_ctrl_port *ctrl_port;
  369. unsigned char msg_len = 0;
  370. int ret = 0;
  371. #if ENABLE_CCMNI
  372. int rx_ch = 0;
  373. #endif
  374. LOGPRT(LOG_NOTICE, "%s: enter\n", __func__);
  375. if (!modem || (modem->status != MD_READY)) {
  376. LOGPRT(LOG_ERR, "%s: md not available now\n", __func__);
  377. goto down_out;
  378. }
  379. /*dump ccmni status */
  380. #if ENABLE_CCMNI
  381. while (rx_ch < CCMNI_INTF_COUNT) {
  382. ccmni_ops.dump(SDIO_MD_ID, rx_ch, 0);
  383. rx_ch++;
  384. }
  385. #endif
  386. ctrl_port = modem->ctrl_port;
  387. wait_event(ctrl_port->sflow_ctrl_wait_q,
  388. (SFLOW_CTRL_DISABLE ==
  389. atomic_read(&ctrl_port->sflow_ctrl_state)
  390. || (modem->status != MD_READY)));
  391. if (down_interruptible(&modem->sem)) {
  392. LOGPRT(LOG_ERR, "%s %d down_interruptible failed.\n", __func__,
  393. __LINE__);
  394. ret = -ERESTARTSYS;
  395. goto down_out;
  396. }
  397. LOGPRT(LOG_ERR, "start heart beat timer %x\n", hear_beat_counter);
  398. /*start heart beat timer, if this timer expires, and still no response from c2k, we assume c2k is dead. */
  399. /*when receive heart beat msg from c2k, delete this timer. */
  400. mod_timer(&modem->heart_beat_timer,
  401. jiffies + msecs_to_jiffies(HEART_BEAT_TIMEOUT));
  402. ret =
  403. contruct_ctrl_chan_msg(ctrl_port, HEART_BEAT_MSG_ID,
  404. (hear_beat_counter >> 8) & 0xFF,
  405. hear_beat_counter & 0xFF);
  406. hear_beat_counter++;
  407. if (ret < 0) {
  408. LOGPRT(LOG_ERR, "%s contruct_ctrl_chan_msg failed\n", __func__);
  409. goto up_sem;
  410. }
  411. msg_len = sizeof(struct ctrl_port_msg);
  412. msg_len = (msg_len + 3) & ~0x03; /*Round up to nearest multiple of 4 */
  413. modem_sdio_write(modem, SDIO_WRITE_ADDR, &(ctrl_port->chan_ctrl_msg),
  414. msg_len);
  415. mod_timer(&modem->poll_timer,
  416. jiffies + msecs_to_jiffies(POLLING_INTERVAL));
  417. up_sem:
  418. up(&modem->sem);
  419. down_out:
  420. return;
  421. }
  422. int force_c2k_assert(struct sdio_modem *modem)
  423. {
  424. struct sdio_modem_ctrl_port *ctrl_port;
  425. unsigned char msg_len = 0;
  426. int ret = 0;
  427. LOGPRT(LOG_INFO, "%s: enter\n", __func__);
  428. if (!modem || (modem->status != MD_READY)) {
  429. LOGPRT(LOG_ERR, "%s: md not available now\n", __func__);
  430. del_timer(&modem->force_assert_timer);
  431. goto down_out;
  432. }
  433. ctrl_port = modem->ctrl_port;
  434. wait_event(ctrl_port->sflow_ctrl_wait_q,
  435. (SFLOW_CTRL_DISABLE ==
  436. atomic_read(&ctrl_port->sflow_ctrl_state)
  437. || (modem->status != MD_READY)));
  438. if (down_interruptible(&modem->sem)) {
  439. LOGPRT(LOG_ERR, "%s %d down_interruptible failed.\n", __func__,
  440. __LINE__);
  441. ret = -ERESTARTSYS;
  442. goto down_out;
  443. }
  444. ret = contruct_ctrl_chan_msg(ctrl_port, FORCE_ASSERT_MSG_ID, 0, 0);
  445. if (ret < 0) {
  446. LOGPRT(LOG_ERR, "%s contruct_ctrl_chan_msg failed\n", __func__);
  447. goto up_sem;
  448. }
  449. msg_len = sizeof(struct ctrl_port_msg);
  450. msg_len = (msg_len + 3) & ~0x03; /*Round up to nearest multiple of 4 */
  451. modem_sdio_write(modem, SDIO_WRITE_ADDR, &(ctrl_port->chan_ctrl_msg),
  452. msg_len);
  453. up_sem:
  454. up(&modem->sem);
  455. down_out:
  456. return ret;
  457. }
  458. static void modem_force_assert_work(struct work_struct *work)
  459. {
  460. struct sdio_modem *modem =
  461. container_of(work, struct sdio_modem, force_assert_work);
  462. force_c2k_assert(modem);
  463. }
  464. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  465. static void modem_smem_read_done_work(struct work_struct *work)
  466. {
  467. struct sdio_modem *modem =
  468. container_of(work, struct sdio_modem, smem_read_done_work);
  469. struct sdio_msg_head *head_to_write;
  470. if (down_interruptible(&modem->sem)) {
  471. LOGPRT(LOG_ERR, "%s %d down_interruptible failed.\n", __func__,
  472. __LINE__);
  473. return;
  474. }
  475. modem->curr_log_blk.id = LOG_AP_DATA_DONE_MSG;
  476. LOGPRT(LOG_INFO, "logging done %x %x %llu\n",
  477. modem->curr_log_blk.address,
  478. modem->curr_log_blk.length, modem->log_blk_stamp);
  479. head_to_write = (struct sdio_msg_head *)modem->trans_buffer;
  480. head_to_write->start_flag = MSG_START_FLAG;
  481. /*port->index start from 0, chanInfo start from 1, chan0 is ctrl channel. */
  482. head_to_write->chanInfo = 0x0F & MD_LOG2_CH_ID;
  483. head_to_write->tranHi = 0x0F & (sizeof(modem->curr_log_blk) >> 8);
  484. head_to_write->tranLow = 0xFF & sizeof(modem->curr_log_blk);
  485. head_to_write->hw_head.len_hi =
  486. 0xFF & ((sizeof(modem->curr_log_blk) + sizeof(struct sdio_msg_head))
  487. >> 8);
  488. head_to_write->hw_head.len_low =
  489. 0xFF & (sizeof(modem->curr_log_blk) + sizeof(struct sdio_msg_head));
  490. memcpy(modem->trans_buffer + sizeof(struct sdio_msg_head),
  491. &modem->curr_log_blk, sizeof(modem->curr_log_blk));
  492. /*ccci_mem_dump(-1, modem->trans_buffer, (sizeof(modem->curr_log_blk) + sizeof(struct sdio_msg_head))); */
  493. modem_sdio_write(modem, SDIO_WRITE_ADDR, modem->trans_buffer,
  494. (sizeof(modem->curr_log_blk) +
  495. sizeof(struct sdio_msg_head)));
  496. up(&modem->sem);
  497. }
  498. #endif
  499. static void c2k_heart_beat_timer(unsigned long data)
  500. {
  501. struct sdio_modem *modem = (struct sdio_modem *)data;
  502. if (modem->status != MD_READY) {
  503. LOGPRT(LOG_ERR, "heart beat timer expired, but modem is not ready!\n");
  504. return;
  505. }
  506. LOGPRT(LOG_ERR,
  507. "heart beat timer expired, cancel poll timer and force c2k assert now!\n");
  508. del_timer(&modem->poll_timer);
  509. schedule_work(&modem->force_assert_work);
  510. /*
  511. start force assert timer, if this timer expires,
  512. and still no response from c2k, we should trigger md long time no response exception.
  513. */
  514. /*when receive MD_EX msg from c2k, delete this timer. */
  515. mod_timer(&modem->force_assert_timer,
  516. jiffies + msecs_to_jiffies(FORCE_ASSERT_TIMEOUT));
  517. }
  518. static void c2k_poll_status_timer(unsigned long data)
  519. {
  520. struct sdio_modem *modem = (struct sdio_modem *)data;
  521. LOGPRT(LOG_INFO, "poll c2k now!\n");
  522. schedule_work(&modem->poll_hb_work);
  523. /*poll_c2k(); */
  524. }
  525. static void c2k_force_assert_timer(unsigned long data)
  526. {
  527. struct sdio_modem *modem = (struct sdio_modem *)data;
  528. int db_opt = DB_OPT_DEFAULT;
  529. char ex_info[EE_BUF_LEN] = ""; /*attention, be careful with string length! */
  530. char buff[AED_STR_LEN];
  531. LOGPRT(LOG_ERR,
  532. "force assert timer expired, trigger md long time no response now!\n");
  533. if (!modem || (modem->status != MD_READY)) {
  534. LOGPRT(LOG_ERR, "%s: md not available now\n", __func__);
  535. goto down_out;
  536. }
  537. dump_c2k_iram();
  538. strcpy(ex_info, "\n[Others] MD3 long time no response\n");
  539. db_opt |= DB_OPT_FTRACE;
  540. snprintf(buff, AED_STR_LEN, "md3:%s%s", ex_info, c2k_img_info_str);
  541. #if defined CONFIG_MTK_AEE_FEATURE
  542. aed_md_exception_api(NULL, 0, NULL, 0, buff, db_opt);
  543. #endif
  544. down_out:
  545. return;
  546. }
  547. #endif /*CONFIG_EVDO_DT_VIA_SUPPORT */
  548. int modem_on_off_ctrl_chan(unsigned char on)
  549. {
  550. struct sdio_modem *modem = c2k_modem;
  551. struct sdio_modem_ctrl_port *ctrl_port;
  552. unsigned char msg_len = 0;
  553. int ret = 0;
  554. LOGPRT(LOG_INFO, "%s: enter, on = %d\n", __func__, on);
  555. if (!modem || (modem->status != MD_READY)) {
  556. LOGPRT(LOG_ERR, "%s: md not available now\n", __func__);
  557. goto down_out;
  558. }
  559. ctrl_port = modem->ctrl_port;
  560. wait_event(ctrl_port->sflow_ctrl_wait_q,
  561. (SFLOW_CTRL_DISABLE ==
  562. atomic_read(&ctrl_port->sflow_ctrl_state)
  563. || (modem->status != MD_READY)));
  564. if (down_interruptible(&modem->sem)) {
  565. LOGPRT(LOG_ERR, "%s %d down_interruptible failed.\n", __func__,
  566. __LINE__);
  567. ret = -ERESTARTSYS;
  568. goto down_out;
  569. }
  570. ret = contruct_ctrl_chan_msg(ctrl_port, CHAN_ONOFF_MSG_ID, 0, on);
  571. if (ret < 0) {
  572. LOGPRT(LOG_ERR, "%s contruct_ctrl_chan_msg failed\n", __func__);
  573. goto up_sem;
  574. }
  575. msg_len = sizeof(struct ctrl_port_msg);
  576. msg_len = (msg_len + 3) & ~0x03; /*Round up to nearest multiple of 4 */
  577. modem_sdio_write(modem, SDIO_WRITE_ADDR, &(ctrl_port->chan_ctrl_msg),
  578. msg_len);
  579. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  580. if (on) {
  581. LOGPRT(LOG_INFO, "%s start polling c2k's status now...\n",
  582. __func__);
  583. /*start poll c2k's status now */
  584. mod_timer(&modem->poll_timer,
  585. jiffies + msecs_to_jiffies(POLLING_INTERVAL));
  586. }
  587. #endif /*CONFIG_EVDO_DT_VIA_SUPPORT */
  588. up_sem:
  589. up(&modem->sem);
  590. down_out:
  591. return ret;
  592. }
  593. /*used by USB for ETS*/
  594. int modem_dtr_set(int on, int low_latency)
  595. {
  596. struct sdio_modem *modem = c2k_modem;
  597. unsigned long flags;
  598. int ret = 0;
  599. spin_lock_irqsave(&modem->status_lock, flags);
  600. if (modem->status == MD_READY) {
  601. spin_unlock_irqrestore(&modem->status_lock, flags);
  602. dtr_value = on;
  603. if (low_latency)
  604. modem_dtr_send(&modem->dtr_work);
  605. else
  606. schedule_work(&modem->dtr_work);
  607. } else {
  608. spin_unlock_irqrestore(&modem->status_lock, flags);
  609. }
  610. return ret;
  611. }
  612. void modem_dtr_send(struct work_struct *work)
  613. {
  614. struct sdio_modem_port *port;
  615. struct sdio_modem_ctrl_port *ctrl_port;
  616. unsigned char control_signal = 0;
  617. unsigned char msg_len = 0;
  618. int ret = 0;
  619. unsigned int on = 0;
  620. struct sdio_modem *modem =
  621. container_of(work, struct sdio_modem, dtr_work);
  622. on = dtr_value;
  623. LOGPRT(LOG_INFO, "%s: enter, on =%d\n", __func__, on);
  624. port = sdio_modem_tty_port_get(0);
  625. ret = check_port(port);
  626. if (ret < 0) {
  627. LOGPRT(LOG_ERR, "%s %d check_port failed\n", __func__,
  628. __LINE__);
  629. goto down_out;
  630. }
  631. modem = port->modem;
  632. ctrl_port = modem->ctrl_port;
  633. wait_event(ctrl_port->sflow_ctrl_wait_q,
  634. (SFLOW_CTRL_DISABLE ==
  635. atomic_read(&ctrl_port->sflow_ctrl_state)
  636. || (modem->status == MD_OFF)));
  637. if (down_interruptible(&modem->sem)) {
  638. LOGPRT(LOG_ERR, "%s %d down_interruptible failed.\n", __func__,
  639. __LINE__);
  640. ret = -ERESTARTSYS;
  641. goto down_out;
  642. }
  643. if (ctrl_port->chan_state == CHAN_ON) {
  644. if (on)
  645. control_signal |= 0x04;
  646. else
  647. control_signal &= 0xFB;
  648. ret =
  649. contruct_ctrl_chan_msg(ctrl_port, MDM_STATUS_IND_MSG_ID, 2,
  650. control_signal);
  651. if (ret < 0) {
  652. LOGPRT(LOG_ERR, "%s contruct_ctrl_chan_msg failed\n",
  653. __func__);
  654. goto up_sem;
  655. }
  656. msg_len = sizeof(struct ctrl_port_msg);
  657. msg_len = (msg_len + 3) & ~0x03; /*Round up to nearest multiple of 4 */
  658. modem_sdio_write(modem, SDIO_WRITE_ADDR,
  659. &(ctrl_port->chan_ctrl_msg), msg_len);
  660. } else {
  661. ret = -1;
  662. LOGPRT(LOG_ERR,
  663. "%s: ctrl channel is off, please turn on first\n",
  664. __func__);
  665. }
  666. up_sem:
  667. up(&modem->sem);
  668. down_out:
  669. return;
  670. }
  671. /*used by USB for ETS*/
  672. int modem_dcd_state(void)
  673. {
  674. unsigned long flags;
  675. /*int ret = 0; */
  676. struct sdio_modem *modem = c2k_modem;
  677. spin_lock_irqsave(&modem->status_lock, flags);
  678. if (modem->status == MD_READY) {
  679. spin_unlock_irqrestore(&modem->status_lock, flags);
  680. schedule_work(&modem->dcd_query_work);
  681. } else {
  682. spin_unlock_irqrestore(&modem->status_lock, flags);
  683. dcd_state = 0;
  684. }
  685. return dcd_state;
  686. }
  687. void modem_dcd_query(struct work_struct *work)
  688. {
  689. struct sdio_modem *modem =
  690. container_of(work, struct sdio_modem, dcd_query_work);
  691. struct sdio_modem_ctrl_port *ctrl_port;
  692. struct sdio_modem_port *port = NULL;
  693. unsigned char msg_len = 0;
  694. int ret = 0;
  695. LOGPRT(LOG_NOTICE, "%s: enter\n", __func__);
  696. /*why use tty port 0???? haow */
  697. port = sdio_modem_tty_port_get(0);
  698. ret = check_port(port);
  699. if (ret < 0) {
  700. LOGPRT(LOG_ERR, "%s %d check_port failed\n", __func__,
  701. __LINE__);
  702. goto down_out;
  703. }
  704. ctrl_port = modem->ctrl_port;
  705. if (ctrl_port->chan_state == CHAN_ON) {
  706. wait_event(ctrl_port->sflow_ctrl_wait_q,
  707. (SFLOW_CTRL_DISABLE ==
  708. atomic_read(&ctrl_port->sflow_ctrl_state)
  709. || (modem->status != MD_READY)));
  710. if (down_interruptible(&modem->sem)) {
  711. LOGPRT(LOG_ERR, "%s %d down_interruptible failed.\n",
  712. __func__, __LINE__);
  713. ret = -ERESTARTSYS;
  714. goto down_out;
  715. }
  716. ret = contruct_ctrl_chan_msg(ctrl_port, MDM_STATUS_QUERY_MSG_ID, 2, 0); /*why use channel 2??? haow */
  717. if (ret < 0) {
  718. LOGPRT(LOG_ERR, "%s contruct_ctrl_chan_msg failed\n",
  719. __func__);
  720. goto up_sem;
  721. }
  722. msg_len = sizeof(struct ctrl_port_msg);
  723. msg_len = (msg_len + 3) & ~0x03; /*Round up to nearest multiple of 4 */
  724. modem_sdio_write(modem, SDIO_WRITE_ADDR,
  725. &(ctrl_port->chan_ctrl_msg), msg_len);
  726. up_sem:
  727. up(&modem->sem);
  728. msleep(20);
  729. dcd_state = port->dtr_state; /*why?? */
  730. } else {
  731. dcd_state = 0;
  732. LOGPRT(LOG_ERR,
  733. "%s: ctrl channel is off, please turn on first\n",
  734. __func__);
  735. }
  736. down_out:
  737. return;
  738. }
  739. int modem_loop_back_chan(unsigned char chan_num, unsigned char opt)
  740. {
  741. struct sdio_modem *modem = c2k_modem;
  742. struct sdio_modem_ctrl_port *ctrl_port;
  743. unsigned char msg_len = 0;
  744. int ret = 0;
  745. LOGPRT(LOG_NOTICE, "%s: enter\n", __func__);
  746. ctrl_port = modem->ctrl_port;
  747. wait_event(ctrl_port->sflow_ctrl_wait_q,
  748. (SFLOW_CTRL_DISABLE ==
  749. atomic_read(&ctrl_port->sflow_ctrl_state)
  750. || (modem->status == MD_OFF)));
  751. if (down_interruptible(&modem->sem)) {
  752. LOGPRT(LOG_ERR, "%s %d down_interruptible failed.\n", __func__,
  753. __LINE__);
  754. ret = -ERESTARTSYS;
  755. goto down_out;
  756. }
  757. if (ctrl_port->chan_state == CHAN_ON) {
  758. loop_back[0] = MSG_START_FLAG;
  759. loop_back[1] = 0;
  760. loop_back[2] = 0; /*High byte of the following payload length */
  761. loop_back[3] = 6; /*Low byte of the following payload length */
  762. loop_back[4] = 0x00; /*High byte of control message ID,for onoff request ID=CHAN_ONOFF_MSG_ID */
  763. loop_back[5] = 0x06; /*Low byte of control message ID,for onoff request ID=CHAN_ONOFF_MSG_ID */
  764. loop_back[6] = 3; /*device id sdio = 3 */
  765. loop_back[7] = opt;
  766. loop_back[8] = chan_num; /*ChanNum ,same as ChanInfo */
  767. loop_back[9] = 0;
  768. msg_len = 12;
  769. msg_len = (msg_len + 3) & ~0x03; /*Round up to nearest multiple of 4 */
  770. modem_sdio_write(modem, SDIO_WRITE_ADDR, &(loop_back[0]),
  771. msg_len);
  772. } else {
  773. ret = -1;
  774. LOGPRT(LOG_ERR,
  775. "%s: ctrl channel is off, please turn on first\n",
  776. __func__);
  777. }
  778. up(&modem->sem);
  779. down_out:
  780. return ret;
  781. }
  782. static int ctrl_msg_analyze(struct sdio_modem *modem)
  783. {
  784. struct sdio_modem_ctrl_port *ctrl_port;
  785. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  786. struct ctrl_port_msg *msg =
  787. (struct ctrl_port_msg *)modem->as_packet->buffer;
  788. #else
  789. struct ctrl_port_msg *msg = modem->msg;
  790. #endif
  791. unsigned int msg_id = (msg->id_hi << 8) + msg->id_low;
  792. unsigned char option = msg->option;
  793. unsigned char chan_num = msg->chan_num;
  794. unsigned char tty_port_idx = 0;
  795. struct sdio_modem_port *port;
  796. unsigned char res;
  797. ctrl_port = modem->ctrl_port;
  798. switch (msg_id) {
  799. case CHAN_ONOFF_MSG_ID:
  800. if (option == 1) {
  801. ctrl_port->chan_state = CHAN_ON;
  802. LOGPRT(LOG_INFO, "%s: ctrl channel is open\n",
  803. __func__);
  804. } else if (option == 0) {
  805. ctrl_port->chan_state = CHAN_OFF;
  806. LOGPRT(LOG_INFO, "%s: ctrl channel is close\n",
  807. __func__);
  808. } else {
  809. LOGPRT(LOG_ERR, "%s: err option value = %d\n",
  810. __func__, option);
  811. }
  812. break;
  813. case MDM_STATUS_IND_MSG_ID:
  814. port = modem->port[0]; /*why use tty port 0??? haow */
  815. if (option & 0x80) { /*connect */
  816. port->dtr_state = 1;
  817. } else { /*disconnect */
  818. port->dtr_state = 0;
  819. }
  820. break;
  821. case MDM_STATUS_QUERY_MSG_ID:
  822. port = modem->port[0]; /*why use tty port 0??? haow */
  823. if (option & 0x80) { /*connect */
  824. port->dtr_state = 1;
  825. } else { /*disconnect */
  826. port->dtr_state = 0;
  827. }
  828. /*to be contionue */
  829. break;
  830. case CHAN_LOOPBACK_TST_MSG_ID:
  831. {
  832. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  833. chan_num =
  834. *(modem->as_packet->buffer +
  835. sizeof(struct sdio_msg_head) + 4);
  836. res =
  837. *(modem->as_packet->buffer +
  838. sizeof(struct sdio_msg_head) + 5);
  839. #else
  840. chan_num = *(modem->msg->buffer + 4);
  841. res = *(modem->msg->buffer + 5);
  842. #endif
  843. if (option == OPT_LOOPBACK_OPEN) { /*open */
  844. LOGPRT(LOG_NOTICE,
  845. "%s %d: open chan %d, result = %d\n",
  846. __func__, __LINE__, chan_num, res);
  847. } else if (option == OPT_LOOPBACK_CLOSE) { /*close */
  848. LOGPRT(LOG_NOTICE,
  849. "%s %d: close chan %d, result = %d\n",
  850. __func__, __LINE__, chan_num, res);
  851. } else if (option == OPT_LOOPBACK_QUERY) { /*close */
  852. LOGPRT(LOG_NOTICE,
  853. "%s %d: query chan %d, result = %d\n",
  854. __func__, __LINE__, chan_num, res);
  855. } else {
  856. LOGPRT(LOG_ERR, "%s %d: unknown option %d\n",
  857. __func__, __LINE__, option);
  858. }
  859. }
  860. break;
  861. case FLOW_CONTROL_MSG_ID:
  862. chan_num = msg->chan_num;
  863. if (chan_num > 0 && chan_num < (SDIO_TTY_NR + 1)) {
  864. tty_port_idx = chan_num - 1;
  865. port = modem->port[tty_port_idx];
  866. if (option == SFLOW_CTRL_ENABLE) {
  867. LOGPRT(LOG_INFO,
  868. "%s %d: channel%d soft flow ctrl enable!\n",
  869. __func__, __LINE__, (port->index + 1));
  870. atomic_set(&port->sflow_ctrl_state,
  871. SFLOW_CTRL_ENABLE);
  872. } else if (option == SFLOW_CTRL_DISABLE) {
  873. LOGPRT(LOG_INFO,
  874. "%s %d: channel%d soft flow ctrl disable!\n",
  875. __func__, __LINE__, (port->index + 1));
  876. atomic_set(&port->sflow_ctrl_state,
  877. SFLOW_CTRL_DISABLE);
  878. wake_up(&port->sflow_ctrl_wait_q);
  879. }
  880. } else if (chan_num == 0) {
  881. if (option == SFLOW_CTRL_ENABLE) {
  882. LOGPRT(LOG_INFO,
  883. "%s %d: ctrl channel soft flow ctrl enable!\n",
  884. __func__, __LINE__);
  885. atomic_set(&ctrl_port->sflow_ctrl_state,
  886. SFLOW_CTRL_ENABLE);
  887. } else if (option == SFLOW_CTRL_DISABLE) {
  888. LOGPRT(LOG_INFO,
  889. "%s %d: ctrl channel soft flow ctrl disable!\n",
  890. __func__, __LINE__);
  891. atomic_set(&ctrl_port->sflow_ctrl_state,
  892. SFLOW_CTRL_DISABLE);
  893. wake_up(&ctrl_port->sflow_ctrl_wait_q);
  894. }
  895. } else {
  896. LOGPRT(LOG_ERR, "%s %d: unknown channel num%d!\n",
  897. __func__, __LINE__, chan_num);
  898. }
  899. break;
  900. case CHAN_SWITCH_REQ_MSG_ID:
  901. /*to be contionue */
  902. break;
  903. case CHAN_STATUS_QUERY_MSG_ID:
  904. /*to be contionue */
  905. break;
  906. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  907. case HEART_BEAT_MSG_ID:
  908. LOGPRT(LOG_INFO, "heart beat msg received %x\n",
  909. (msg->chan_num << 8) | msg->option);
  910. del_timer(&modem->heart_beat_timer);
  911. break;
  912. #endif
  913. default:
  914. LOGPRT(LOG_ERR, "%s %d: unknown control message received\n",
  915. __func__, __LINE__);
  916. goto err_wrong_format;
  917. }
  918. return 0;
  919. err_wrong_format:
  920. return -1;
  921. }
  922. #if !ENABLE_CHAR_DEV
  923. static void sdio_buffer_in_print(struct sdio_modem_port *port,
  924. struct sdio_buf_in_packet *packet)
  925. {
  926. unsigned int count;
  927. int i;
  928. pr_debug("[MODEM SDIO] sdio channel%d buffer in %d bytes data<<",
  929. (port->index + 1), packet->size);
  930. count = packet->size;
  931. if (count > 20)
  932. count = 20;
  933. for (i = 0; i < count; i++)
  934. pr_cont("%x-", *(packet->buffer + i));
  935. pr_cont("\n");
  936. }
  937. /*when tty port is closed, modem may send data to the corresponding channel too. We buffered those data.*/
  938. /*So, when tty port opened, we should push those buffered data to user.*/
  939. static void sdio_buf_in_tty_work(struct sdio_modem_port *port)
  940. {
  941. struct sdio_buf_in_packet *packet = NULL;
  942. struct tty_struct *tty;
  943. int room;
  944. tty = tty_port_tty_get(&port->port);
  945. if (tty) {
  946. while (!list_empty(&port->sdio_buf_in_list)) {
  947. packet =
  948. list_first_entry(&port->sdio_buf_in_list,
  949. struct sdio_buf_in_packet, node);
  950. room =
  951. tty_buffer_request_room(&port->port, packet->size);
  952. if (room < packet->size) {
  953. LOGPRT(LOG_ERR,
  954. "%s %d: no room in tty rx buffer!\n",
  955. __func__, __LINE__);
  956. } else {
  957. room =
  958. tty_insert_flip_string(&port->port,
  959. packet->buffer,
  960. packet->size);
  961. if (room < packet->size) {
  962. LOGPRT(LOG_ERR,
  963. "%s %d: couldn't insert all characters (TTY is full?)!\n",
  964. __func__, __LINE__);
  965. } else {
  966. tty_flip_buffer_push(&port->port);
  967. }
  968. }
  969. sdio_buffer_in_print(port, packet);
  970. list_del(&packet->node);
  971. if (packet) {
  972. port->sdio_buf_in_size -= packet->size;
  973. kfree(packet->buffer);
  974. kfree(packet);
  975. }
  976. port->sdio_buf_in_num--;
  977. }
  978. }
  979. tty_kref_put(tty);
  980. }
  981. /*****************************************************************************
  982. *tty driver interface functions
  983. *****************************************************************************/
  984. /**
  985. *sdio_uart_install - install method
  986. *@driver: the driver in use (sdio_uart in our case)
  987. *@tty: the tty being bound
  988. *
  989. *Look up and bind the tty and the driver together. Initialize
  990. *any needed private data (in our case the termios)
  991. */
  992. static int modem_tty_install(struct tty_driver *driver, struct tty_struct *tty)
  993. {
  994. struct sdio_modem_port *port;
  995. int idx = tty->index;
  996. int ret;
  997. port = sdio_modem_tty_port_get(idx);
  998. LOGPRT(LOG_INFO, "%s %d: port %d.\n", __func__, __LINE__, port->index);
  999. if (!port) {
  1000. tty->driver_data = NULL;
  1001. LOGPRT(LOG_ERR, "%s %d can't find sdio modem port.\n", __func__,
  1002. __LINE__);
  1003. return -ENODEV;
  1004. }
  1005. kref_get(&port->kref);
  1006. ret = tty_port_install(&port->port, driver, tty);
  1007. if (ret == 0)
  1008. /*This is the ref sdio_uart_port get provided */
  1009. tty->driver_data = port;
  1010. else
  1011. sdio_modem_tty_port_put(port);
  1012. return ret;
  1013. }
  1014. /**
  1015. *sdio_uart_cleanup - called on the last tty kref drop
  1016. *@tty: the tty being destroyed
  1017. *
  1018. *Called asynchronously when the last reference to the tty is dropped.
  1019. *We cannot destroy the tty->driver_data port kref until this point
  1020. */
  1021. static void modem_tty_cleanup(struct tty_struct *tty)
  1022. {
  1023. struct sdio_modem_port *port = tty->driver_data;
  1024. tty->driver_data = NULL; /*Bug trap */
  1025. if (port) {
  1026. LOGPRT(LOG_INFO, "%s %d: port %d.\n", __func__, __LINE__,
  1027. port->index);
  1028. sdio_modem_tty_port_put(port);
  1029. } else {
  1030. LOGPRT(LOG_ERR, "%s %d: invalid port.\n", __func__, __LINE__);
  1031. }
  1032. }
  1033. static int modem_tty_open(struct tty_struct *tty, struct file *filp)
  1034. {
  1035. struct sdio_modem_port *port = tty->driver_data;
  1036. LOGPRT(LOG_INFO, "%s %d: port %d.\n", __func__, __LINE__, port->index);
  1037. return tty_port_open(&port->port, tty, filp);
  1038. }
  1039. static void modem_tty_close(struct tty_struct *tty, struct file *filp)
  1040. {
  1041. struct sdio_modem_port *port = tty->driver_data;
  1042. LOGPRT(LOG_INFO, "%s %d: port %d.\n", __func__, __LINE__, port->index);
  1043. tty_port_close(&port->port, tty, filp);
  1044. }
  1045. static void modem_tty_hangup(struct tty_struct *tty)
  1046. {
  1047. struct sdio_modem_port *port = tty->driver_data;
  1048. LOGPRT(LOG_INFO, "%s %d: port %d.\n", __func__, __LINE__, port->index);
  1049. tty_port_hangup(&port->port);
  1050. }
  1051. static int modem_tty_write(struct tty_struct *tty, const unsigned char *buf,
  1052. int count)
  1053. {
  1054. struct sdio_modem_port *port = tty->driver_data;
  1055. struct sdio_modem *modem = c2k_modem;
  1056. unsigned long flags;
  1057. int ret = 0;
  1058. ret = check_port(port);
  1059. if (ret < 0) {
  1060. LOGPRT(LOG_ERR, "%s %d check_port failed\n", __func__,
  1061. __LINE__);
  1062. return ret;
  1063. }
  1064. if (port->inception)
  1065. return -EBUSY;
  1066. if (count > FIFO_SIZE) {
  1067. LOGPRT(LOG_ERR, "%s %d FIFO size is not enough!\n", __func__,
  1068. __LINE__);
  1069. return -1;
  1070. }
  1071. spin_lock_irqsave(&modem->status_lock, flags);
  1072. if (modem->status != MD_OFF) {
  1073. spin_unlock_irqrestore(&modem->status_lock, flags);
  1074. ret =
  1075. kfifo_in_locked(&port->transmit_fifo, buf, count,
  1076. &port->write_lock);
  1077. queue_work(port->write_q, &port->write_work);
  1078. } else {
  1079. spin_unlock_irqrestore(&modem->status_lock, flags);
  1080. LOGPRT(LOG_ERR, "%s %d: port%d is removed!\n", __func__,
  1081. __LINE__, port->index);
  1082. }
  1083. LOGPRT(LOG_DEBUG, "%s %d: port%d\n", __func__, __LINE__, port->index);
  1084. return ret;
  1085. }
  1086. static int modem_tty_write_room(struct tty_struct *tty)
  1087. {
  1088. struct sdio_modem_port *port = tty->driver_data;
  1089. unsigned long flags = 0;
  1090. unsigned int data_len = 0;
  1091. int ret;
  1092. ret = check_port(port);
  1093. if (ret < 0) {
  1094. LOGPRT(LOG_ERR, "%s %d check_port failed\n", __func__,
  1095. __LINE__);
  1096. return ret;
  1097. }
  1098. spin_lock_irqsave(&port->write_lock, flags);
  1099. data_len = FIFO_SIZE - kfifo_len(&port->transmit_fifo);
  1100. spin_unlock_irqrestore(&port->write_lock, flags);
  1101. LOGPRT(LOG_DEBUG, "%s %d: port %d free size %d.\n", __func__, __LINE__,
  1102. port->index, data_len);
  1103. return data_len;
  1104. }
  1105. #if 0
  1106. static void modem_tty_flush_chars(struct tty_struct *tty)
  1107. {
  1108. struct sdio_modem_port *port = tty->driver_data;
  1109. struct sdio_modem *modem;
  1110. unsigned int count;
  1111. unsigned int left, todo;
  1112. unsigned int write_len;
  1113. unsigned int fifo_size;
  1114. unsigned long flags = 0;
  1115. int ret = 0;
  1116. modem = port->modem;
  1117. if (down_interruptible(&modem->sem)) {
  1118. LOGPRT(LOG_ERR, "%s %d down_interruptible failed.\n", __func__,
  1119. __LINE__);
  1120. ret = -ERESTARTSYS;
  1121. goto down_out;
  1122. }
  1123. spin_lock_irqsave(&port->write_lock, flags);
  1124. count = kfifo_len(&port->transmit_fifo);
  1125. spin_unlock_irqrestore(&port->write_lock, flags);
  1126. if (count == 0) {
  1127. up(&modem->sem);
  1128. goto down_out;
  1129. }
  1130. left = count;
  1131. do {
  1132. todo = left;
  1133. if (todo > TRANSMIT_MAX_SIZE - 1)
  1134. todo = TRANSMIT_MAX_SIZE;
  1135. else if (todo > 508)
  1136. todo = 508;
  1137. *modem->trans_buffer = MSG_START_FLAG;
  1138. *(modem->trans_buffer + 1) = 0x0F & (port->index + 1);
  1139. *(modem->trans_buffer + 2) = 0x0F & (todo >> 8);
  1140. *(modem->trans_buffer + 3) = 0xFF & todo;
  1141. fifo_size =
  1142. kfifo_out_locked(&port->transmit_fifo,
  1143. modem->trans_buffer + 4, todo,
  1144. &port->write_lock);
  1145. if (todo != fifo_size) {
  1146. LOGPRT(LOG_ERR,
  1147. "%s %d: port%d todo != kfifo lock out size.\n",
  1148. __func__, __LINE__, port->index);
  1149. todo = fifo_size;
  1150. }
  1151. write_len = (todo + 4 + 3) & ~0x03; /*Round up to nearest multiple of 4 */
  1152. modem_sdio_write(modem, SDIO_WRITE_ADDR, modem->trans_buffer,
  1153. write_len);
  1154. left -= todo;
  1155. } while (left);
  1156. up(&modem->sem);
  1157. down_out:
  1158. /*for compile warning */
  1159. LOGPRT(LOG_DEBUG, "%s %d: port%d.\n", __func__, __LINE__, port->index);
  1160. ret = ret;
  1161. }
  1162. #endif
  1163. static int modem_tty_chars_in_buffer(struct tty_struct *tty)
  1164. {
  1165. struct sdio_modem_port *port = tty->driver_data;
  1166. struct sdio_modem *modem = port->modem;
  1167. unsigned long flags = 0;
  1168. unsigned int data_len = 0;
  1169. int ret;
  1170. /*return 0 when modem is off, because tty driver will wait 30s until chars is buffer return valid value. */
  1171. /*if exit flight mode, flashless will take 30s to exit. and exit flight mode time will be too long. */
  1172. if (modem && (modem->status == MD_OFF))
  1173. return 0;
  1174. ret = check_port(port);
  1175. if (ret < 0) {
  1176. LOGPRT(LOG_ERR, "%s %d ret=%d\n", __func__, __LINE__, ret);
  1177. return ret;
  1178. }
  1179. spin_lock_irqsave(&port->write_lock, flags);
  1180. data_len = kfifo_len(&port->transmit_fifo);
  1181. spin_unlock_irqrestore(&port->write_lock, flags);
  1182. LOGPRT(LOG_DEBUG, "%s %d: port %d chars in buffer %d.\n", __func__,
  1183. __LINE__, port->index, data_len);
  1184. return data_len;
  1185. }
  1186. static void modem_tty_set_termios(struct tty_struct *tty,
  1187. struct ktermios *old_termios)
  1188. {
  1189. struct sdio_modem_port *port = tty->driver_data;
  1190. int ret;
  1191. ret = check_port(port);
  1192. if (ret < 0) {
  1193. LOGPRT(LOG_ERR, "%s %d ret=%d\n", __func__, __LINE__, ret);
  1194. return;
  1195. }
  1196. tty_termios_copy_hw(&tty->termios, old_termios);
  1197. }
  1198. static int modem_tty_tiocmget(struct tty_struct *tty)
  1199. {
  1200. struct sdio_modem_port *port = tty->driver_data;
  1201. int ret;
  1202. ret = check_port(port);
  1203. if (ret < 0) {
  1204. LOGPRT(LOG_ERR, "%s %d ret=%d\n", __func__, __LINE__, ret);
  1205. return ret;
  1206. }
  1207. return 0;
  1208. }
  1209. static int modem_tty_tiocmset(struct tty_struct *tty,
  1210. unsigned int set, unsigned int clear)
  1211. {
  1212. struct sdio_modem_port *port = tty->driver_data;
  1213. int ret;
  1214. ret = check_port(port);
  1215. if (ret < 0) {
  1216. LOGPRT(LOG_ERR, "%s %d ret=%d\n", __func__, __LINE__, ret);
  1217. return ret;
  1218. }
  1219. return 0;
  1220. }
  1221. /*called from tty_port_open*/
  1222. static int sdio_modem_activate(struct tty_port *tport, struct tty_struct *tty)
  1223. {
  1224. struct sdio_modem_port *port = NULL;
  1225. LOGPRT(LOG_INFO, "%s %d: enter.\n", __func__, __LINE__);
  1226. port = container_of(tport, struct sdio_modem_port, port);
  1227. kfifo_reset(&port->transmit_fifo);
  1228. mutex_lock(&port->sdio_buf_in_mutex);
  1229. if (port->sdio_buf_in == 1) {
  1230. sdio_buf_in_tty_work(port); /*maybe pending data in buffer, push to user */
  1231. port->sdio_buf_in = 0;
  1232. }
  1233. mutex_unlock(&port->sdio_buf_in_mutex);
  1234. /*
  1235. *If not set this flag, when user's writing size exceeds 2048,
  1236. *tty will split those data into 2048 + left size.
  1237. */
  1238. set_bit(TTY_NO_WRITE_SPLIT, &tty->flags);
  1239. LOGPRT(LOG_INFO, "%s %d: Leave.\n", __func__, __LINE__);
  1240. return 0;
  1241. }
  1242. /*called when the last close completes or a hangup finishes*/
  1243. static void sdio_modem_shutdown(struct tty_port *tport)
  1244. {
  1245. struct sdio_modem_port *port = NULL;
  1246. struct sdio_buf_in_packet *packet = NULL;
  1247. LOGPRT(LOG_INFO, "%s %d: enter.\n", __func__, __LINE__);
  1248. port = container_of(tport, struct sdio_modem_port, port);
  1249. mutex_lock(&port->sdio_buf_in_mutex);
  1250. /*clear pending data */
  1251. while (!list_empty(&port->sdio_buf_in_list)) {
  1252. packet =
  1253. list_first_entry(&port->sdio_buf_in_list,
  1254. struct sdio_buf_in_packet, node);
  1255. list_del(&packet->node);
  1256. if (packet) {
  1257. kfree(packet->buffer);
  1258. kfree(packet);
  1259. }
  1260. }
  1261. mutex_unlock(&port->sdio_buf_in_mutex);
  1262. LOGPRT(LOG_INFO, "%s %d: Leave.\n", __func__, __LINE__);
  1263. }
  1264. static const struct tty_port_operations sdio_modem_port_ops = {
  1265. .shutdown = sdio_modem_shutdown,
  1266. .activate = sdio_modem_activate,
  1267. };
  1268. static const struct tty_operations modem_tty_ops = {
  1269. .open = modem_tty_open,
  1270. .close = modem_tty_close,
  1271. .write = modem_tty_write,
  1272. .write_room = modem_tty_write_room,
  1273. .chars_in_buffer = modem_tty_chars_in_buffer,
  1274. /*.flush_chars = modem_tty_flush_chars, */
  1275. .set_termios = modem_tty_set_termios,
  1276. .tiocmget = modem_tty_tiocmget,
  1277. .tiocmset = modem_tty_tiocmset,
  1278. .hangup = modem_tty_hangup,
  1279. .install = modem_tty_install,
  1280. .cleanup = modem_tty_cleanup,
  1281. };
  1282. #endif
  1283. #if ENABLE_CCMNI
  1284. /*When send data to ccmni port, we should analyze msg header first, so we separate ccmni port work from others*/
  1285. static void sdio_write_ccmni_work(struct work_struct *work)
  1286. {
  1287. struct sdio_modem_port *ccmni_port = NULL;
  1288. struct sdio_modem *modem = NULL;
  1289. unsigned int left = 0;
  1290. unsigned int data_len = 0;
  1291. unsigned long flags = 0;
  1292. unsigned int fifo_total_count = 0;
  1293. unsigned int todo = 0;
  1294. unsigned int fifo_read_size = 0;
  1295. unsigned int tx_ch = 0;
  1296. unsigned int write_len = 0;
  1297. struct sdio_msg_head msg_head;
  1298. struct sdio_msg_head *head_to_write;
  1299. struct sk_buff *skb = NULL;
  1300. int ret = 0;
  1301. ccmni_port =
  1302. container_of(work, struct sdio_modem_port, write_ccmni_work);
  1303. modem = ccmni_port->modem;
  1304. LOGPRT(LOG_NOTICE, "%s %d enter.\n", __func__, __LINE__);
  1305. if (down_interruptible(&ccmni_port->write_sem)) {
  1306. LOGPRT(LOG_ERR, "%s %d down_interruptible failed.\n", __func__,
  1307. __LINE__);
  1308. ret = -ERESTARTSYS;
  1309. goto down_out;
  1310. }
  1311. spin_lock_irqsave(&ccmni_port->write_lock, flags);
  1312. fifo_total_count = kfifo_len(&ccmni_port->transmit_fifo);
  1313. spin_unlock_irqrestore(&ccmni_port->write_lock, flags);
  1314. retry_get_skb:
  1315. if (ccmni_port->index == CCMNI_AP_LOOPBACK_CH - 1) {
  1316. /*for loopback */
  1317. LOGPRT(LOG_INFO, "%s %d request skb from kernel.\n", __func__,
  1318. __LINE__);
  1319. skb = dev_alloc_skb(1500);
  1320. if (!skb) {
  1321. msleep(100);
  1322. goto retry_get_skb;
  1323. }
  1324. LOGPRT(LOG_INFO, "%s %d got skb.\n", __func__, __LINE__);
  1325. }
  1326. while (fifo_total_count > 0) {
  1327. todo = sizeof(struct sdio_msg_head);
  1328. fifo_read_size =
  1329. kfifo_out_locked(&ccmni_port->transmit_fifo, &msg_head,
  1330. todo, &ccmni_port->write_lock);
  1331. fifo_total_count -= fifo_read_size;
  1332. if (fifo_read_size != todo) {
  1333. LOGPRT(LOG_ERR,
  1334. "%s %d: fail to get msg head size, just got %d bytes.\n",
  1335. __func__, __LINE__, fifo_read_size);
  1336. /*todo */
  1337. }
  1338. LOGPRT(LOG_DEBUG,
  1339. "%s %d read %d bytes, check header!(0x%x, 0x%x)\n",
  1340. __func__, __LINE__, fifo_read_size, msg_head.start_flag,
  1341. msg_head.chanInfo);
  1342. /*sanity check */
  1343. if ((msg_head.start_flag != 0xFE)
  1344. || ((msg_head.chanInfo & 0x0F) != ccmni_port->index + 1)) {
  1345. LOGPRT(LOG_ERR,
  1346. "%s %d check head fail when write.(0x%x, 0x%x)\n",
  1347. __func__, __LINE__, msg_head.start_flag,
  1348. msg_head.chanInfo);
  1349. ret = -1;
  1350. goto head_err_out;
  1351. }
  1352. data_len = (((msg_head.tranHi & 0x0F) << 8) |
  1353. (msg_head.tranLow & 0xFF));
  1354. tx_ch = (msg_head.chanInfo & 0xF0) >> 4;
  1355. LOGPRT(LOG_DEBUG,
  1356. "%s %d: sdio head 0x%x, ch%d, tx_id%d, len%d\n",
  1357. __func__, __LINE__, msg_head.start_flag,
  1358. msg_head.chanInfo & 0x0F, tx_ch, data_len);
  1359. left = data_len;
  1360. if (ccmni_port->index != CCMNI_AP_LOOPBACK_CH - 1) {
  1361. wait_event(ccmni_port->sflow_ctrl_wait_q,
  1362. (SFLOW_CTRL_DISABLE ==
  1363. atomic_read(&ccmni_port->sflow_ctrl_state)
  1364. || (modem->status == MD_OFF)));
  1365. } else { /*just for AP loopback */
  1366. LOGPRT(LOG_INFO, "%s: data from ccmni...\n", __func__);
  1367. }
  1368. if (down_interruptible(&modem->sem)) {
  1369. LOGPRT(LOG_ERR, "%s %d down_interruptible failed.\n",
  1370. __func__, __LINE__);
  1371. ret = -ERESTARTSYS;
  1372. goto down_sem_fail;
  1373. }
  1374. do {
  1375. todo = left;
  1376. if (todo > TRANSMIT_MAX_SIZE)
  1377. todo = TRANSMIT_MAX_SIZE;
  1378. #ifdef CONFIG_EVDO_DT_VIA_SUPPORT
  1379. if (todo > 508)
  1380. todo = 508;
  1381. #endif
  1382. head_to_write =
  1383. (struct sdio_msg_head *)modem->trans_buffer;
  1384. head_to_write->start_flag = MSG_START_FLAG;
  1385. /*port->index start from 0, chanInfo start from 1, chan0 is ctrl channel. */
  1386. head_to_write->chanInfo =
  1387. (0x0F & (ccmni_port->index + 1)) +
  1388. (0xF0 & (tx_ch << 4));
  1389. head_to_write->tranHi = 0x0F & (todo >> 8);
  1390. head_to_write->tranLow = 0xFF & todo;
  1391. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  1392. head_to_write->hw_head.len_hi =
  1393. 0xFF & ((todo + sizeof(struct sdio_msg_head)) >> 8);
  1394. head_to_write->hw_head.len_low =
  1395. 0xFF & (todo + sizeof(struct sdio_msg_head));
  1396. #endif
  1397. /*to indicate there is data left, not whole packet */
  1398. if (left > todo)
  1399. head_to_write->tranHi |= MORE_DATA_FOLLOWING;
  1400. fifo_read_size =
  1401. kfifo_out_locked(&ccmni_port->transmit_fifo,
  1402. modem->trans_buffer +
  1403. sizeof(struct sdio_msg_head), todo,
  1404. &ccmni_port->write_lock);
  1405. LOGPRT(LOG_DEBUG, "%s %d: fifo_read_size(%d).\n",
  1406. __func__, __LINE__, fifo_read_size);
  1407. if (todo != fifo_read_size) {
  1408. LOGPRT(LOG_ERR,
  1409. "%s %d: port%d todo(%d) != kfifo_lock_out size(%d).\n",
  1410. __func__, __LINE__, ccmni_port->index,
  1411. todo, fifo_read_size);
  1412. todo = fifo_read_size;
  1413. }
  1414. /*Round up to nearest multiple of 4 */
  1415. write_len =
  1416. (todo + sizeof(struct sdio_msg_head) + 3) & ~0x03;
  1417. /*for loop back */
  1418. if (ccmni_port->index == CCMNI_AP_LOOPBACK_CH - 1) {
  1419. memcpy(skb_put(skb, todo),
  1420. modem->trans_buffer +
  1421. sizeof(struct sdio_msg_head), todo);
  1422. /*the last packet of skb received */
  1423. if ((head_to_write->tranHi & 0x20) == 0) {
  1424. LOGPRT(LOG_INFO,
  1425. "%s: data loopback to ccmni...\n",
  1426. __func__);
  1427. sdio_tx_rx_printk(skb, 1);
  1428. ccmni_ops.rx_callback(SDIO_MD_ID, tx_ch,
  1429. skb, NULL);
  1430. }
  1431. } else {
  1432. LOGPRT(LOG_DEBUG,
  1433. "%s %d: port%d sending to md(len %d).\n",
  1434. __func__, __LINE__, ccmni_port->index,
  1435. write_len);
  1436. modem_sdio_write(modem, SDIO_WRITE_ADDR,
  1437. modem->trans_buffer,
  1438. write_len);
  1439. }
  1440. left -= todo;
  1441. } while (left);
  1442. fifo_total_count -= data_len;
  1443. spin_lock_irqsave(&ccmni_port->tx_state_lock, flags);
  1444. if (ccmni_port->tx_state == CCMNI_TX_STOP) {
  1445. if (kfifo_len(&ccmni_port->transmit_fifo) <= FIFO_SIZE/2) {
  1446. /*resume tx queue */
  1447. LOGPRT(LOG_INFO, "ccmni(ch:%d) is resumed.\n",
  1448. tx_ch);
  1449. ccmni_ops.md_state_callback(SDIO_MD_ID, tx_ch,
  1450. TX_IRQ);
  1451. ccmni_port->tx_state = CCMNI_TX_READY;
  1452. } else {
  1453. LOGPRT(LOG_INFO,
  1454. "ccmni(ch:%d) is stopped, fifo_total_count(%d).\n",
  1455. tx_ch, fifo_total_count);
  1456. }
  1457. }
  1458. spin_unlock_irqrestore(&ccmni_port->tx_state_lock, flags);
  1459. up(&modem->sem);
  1460. }
  1461. head_err_out:
  1462. down_sem_fail:
  1463. up(&ccmni_port->write_sem);
  1464. down_out:
  1465. /*for compile warning */
  1466. return;
  1467. }
  1468. #endif
  1469. static void sdio_write_port_work(struct work_struct *work)
  1470. {
  1471. struct sdio_modem_port *port;
  1472. struct sdio_modem *modem;
  1473. struct sdio_msg_head *msg_head;
  1474. /*struct tty_struct *tty; */
  1475. unsigned int count;
  1476. unsigned int left, todo;
  1477. unsigned int write_len;
  1478. unsigned int fifo_size;
  1479. unsigned long flags = 0;
  1480. unsigned int ready_data_count = 0;
  1481. int ret = 0;
  1482. port = container_of(work, struct sdio_modem_port, write_work);
  1483. modem = port->modem;
  1484. if (down_interruptible(&port->write_sem)) {
  1485. LOGPRT(LOG_ERR, "%s %d down_interruptible failed.\n", __func__,
  1486. __LINE__);
  1487. ret = -ERESTARTSYS;
  1488. goto down_out;
  1489. }
  1490. spin_lock_irqsave(&port->write_lock, flags);
  1491. ready_data_count = kfifo_len(&port->transmit_fifo);
  1492. spin_unlock_irqrestore(&port->write_lock, flags);
  1493. if ((port->index == (EXCP_CTRL_CH_ID - 1))
  1494. || (port->index == (EXCP_MSG_CH_ID - 1))) {
  1495. LOGPRT(LOG_INFO, "port%d write work sched(len%d,fc%d)\n",
  1496. port->index, ready_data_count,
  1497. atomic_read(&port->sflow_ctrl_state));
  1498. }
  1499. while (ready_data_count > 0) {
  1500. /*for AT command problem of /r; */
  1501. count = ready_data_count;
  1502. if (count == 0) {
  1503. up(&port->write_sem);
  1504. goto down_out;
  1505. /*md side buffer max size is 5200, so we set this limitation */
  1506. } else if (count > ONE_PACKET_MAX_SIZE) {
  1507. LOGPRT(LOG_DEBUG,
  1508. "%s %d more than packet limit data in fifo (%d)...\n",
  1509. __func__, __LINE__, count);
  1510. if (port->index == (DATA_CH_ID - 1))
  1511. count = ONE_PACKET_MAX_SIZE;
  1512. }
  1513. left = count;
  1514. wait_event(port->sflow_ctrl_wait_q,
  1515. (SFLOW_CTRL_DISABLE ==
  1516. atomic_read(&port->sflow_ctrl_state)
  1517. || (modem->status == MD_OFF)));
  1518. /*make sure whole packet sent to modem without disturbance. */
  1519. if (down_interruptible(&modem->sem)) {
  1520. LOGPRT(LOG_ERR, "%s %d down_interruptible failed.\n",
  1521. __func__, __LINE__);
  1522. ret = -ERESTARTSYS;
  1523. goto down_sem_fail;
  1524. }
  1525. do {
  1526. todo = left;
  1527. if (todo > TRANSMIT_MAX_SIZE)
  1528. todo = TRANSMIT_MAX_SIZE;
  1529. #ifdef CONFIG_EVDO_DT_VIA_SUPPORT
  1530. if (todo > 508)
  1531. todo = 508;
  1532. #endif
  1533. msg_head = (struct sdio_msg_head *)modem->trans_buffer;
  1534. msg_head->start_flag = MSG_START_FLAG;
  1535. /*port->index start from 0, chanInfo start from 1, chan0 is ctrl channel. */
  1536. msg_head->chanInfo = 0x0F & (port->index + 1);
  1537. msg_head->tranHi = 0x0F & (todo >> 8);
  1538. msg_head->tranLow = 0xFF & todo;
  1539. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  1540. msg_head->hw_head.len_hi =
  1541. 0xFF & ((todo + sizeof(struct sdio_msg_head)) >> 8);
  1542. msg_head->hw_head.len_low =
  1543. 0xFF & (todo + sizeof(struct sdio_msg_head));
  1544. #endif
  1545. fifo_size =
  1546. kfifo_out_locked(&port->transmit_fifo,
  1547. modem->trans_buffer +
  1548. sizeof(struct sdio_msg_head), todo,
  1549. &port->write_lock);
  1550. if (todo != fifo_size) {
  1551. LOGPRT(LOG_ERR,
  1552. "%s %d: port%d todo(%d) != kfifo lock out size(%d).\n",
  1553. __func__, __LINE__, port->index, todo,
  1554. fifo_size);
  1555. todo = fifo_size;
  1556. }
  1557. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  1558. if (fifo_size < left)
  1559. msg_head->tranHi |= MORE_DATA_FOLLOWING;
  1560. #endif
  1561. /*Round up to nearest multiple of 4 */
  1562. write_len =
  1563. (todo + sizeof(struct sdio_msg_head) + 3) & ~0x03;
  1564. LOGPRT(LOG_DEBUG, "%s %d write %d bytes.\n", __func__,
  1565. __LINE__, write_len);
  1566. modem_sdio_write(modem, SDIO_WRITE_ADDR,
  1567. modem->trans_buffer, write_len);
  1568. left -= todo;
  1569. } while (left);
  1570. up(&modem->sem);
  1571. ready_data_count -= count;
  1572. LOGPRT(LOG_DEBUG, "%s %d data count %d, just send %d.\n",
  1573. __func__, __LINE__, ready_data_count, left);
  1574. }
  1575. spin_lock_irqsave(&port->write_lock, flags);
  1576. count = kfifo_len(&port->transmit_fifo);
  1577. spin_unlock_irqrestore(&port->write_lock, flags);
  1578. #if !ENABLE_CHAR_DEV
  1579. if (count < SDIO_WAKEUP_CHARS) {
  1580. tty = tty_port_tty_get(&port->port);
  1581. if (tty) {
  1582. /*to inform the line discipline that driver is ready to receive more output data */
  1583. tty_wakeup(tty);
  1584. tty_kref_put(tty); /*tty_port_tty_get() has get reference of tty, should release it */
  1585. }
  1586. }
  1587. #endif
  1588. down_sem_fail:
  1589. up(&port->write_sem);
  1590. down_out:
  1591. /*for compile warning */
  1592. ret = ret;
  1593. }
  1594. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  1595. static int sdio_func1_wr(struct sdio_func *func, unsigned int addr, void *src,
  1596. int count)
  1597. {
  1598. int ret = 0;
  1599. unsigned int cnt = 500;
  1600. while (cnt--) {
  1601. ret = sdio_writesb(func, addr, src, count);
  1602. if (ret) {
  1603. LOGPRT(LOG_ERR,
  1604. "%s %d: write 0x%x failed ret=%d, retry\n",
  1605. __func__, __LINE__, addr, ret);
  1606. msleep(20);
  1607. continue;
  1608. }
  1609. return 0;
  1610. }
  1611. LOGPRT(LOG_ERR, "%s %d: write 0x%x failed ret=%d\n", __func__, __LINE__,
  1612. addr, ret);
  1613. return -1;
  1614. }
  1615. static int sdio_func1_rd(struct sdio_func *func, void *dst, unsigned int addr,
  1616. int count)
  1617. {
  1618. int ret = 0;
  1619. unsigned int cnt = 500;
  1620. while (cnt--) {
  1621. ret = sdio_readsb(func, dst, addr, count);
  1622. if (ret) {
  1623. LOGPRT(LOG_ERR,
  1624. "%s %d: read 0x%x failed ret=%d, retry\n",
  1625. __func__, __LINE__, addr, ret);
  1626. msleep(20);
  1627. continue;
  1628. }
  1629. return 0;
  1630. }
  1631. LOGPRT(LOG_ERR, "%s %d: read 0x%x failed ret=%d\n", __func__, __LINE__,
  1632. addr, ret);
  1633. return -1;
  1634. }
  1635. int sdio_pio_rx_pkt(struct sdio_func *func, char *rx_buf, int pkt_len)
  1636. {
  1637. int blk_sz = DEFAULT_BLK_SIZE;
  1638. int rx_len;
  1639. int ret = 0;
  1640. /*int cnt = 0; */
  1641. if (pkt_len > RX_FIFO_SZ) {
  1642. LOGPRT(LOG_ERR, "rx pkt len %d bytes > DEV_RX_FIFO_SZ:%d\n",
  1643. pkt_len, RX_FIFO_SZ);
  1644. return -1;
  1645. }
  1646. if (pkt_len == 0) {
  1647. LOGPRT(LOG_ERR, "!!!! rx pkt len %d bytes !!!!\n", pkt_len);
  1648. return -1;
  1649. }
  1650. if (pkt_len < blk_sz) {
  1651. #if PADDING_BY_BLOCK_SIZE
  1652. rx_len = blk_sz;
  1653. #else
  1654. rx_len = (pkt_len + 3) / 4 * 4;
  1655. #endif
  1656. } else {
  1657. rx_len = (pkt_len + blk_sz - 1) / blk_sz * blk_sz;
  1658. }
  1659. ret = sdio_func1_rd(func, rx_buf, SDIO_CRDR, rx_len);
  1660. if (ret) {
  1661. LOGPRT(LOG_ERR, "%s %d: read rx data failed ret=%d\n", __func__,
  1662. __LINE__, ret);
  1663. }
  1664. LOGPRT(LOG_NOTICE, "read %d bytes: ", rx_len);
  1665. #if USE_CCIF_INTR
  1666. ccif_notify_c2k(RX_DONE_CH);
  1667. #endif
  1668. #if 0
  1669. int i = 0;
  1670. for (i = 0; i < rx_len; i++)
  1671. LOGPRT(LOG_DEBUG, "%x-", *(rx_buf + i));
  1672. LOGPRT(LOG_NOTICE, "\n");
  1673. #endif
  1674. return ret ? (-1) : 0;
  1675. }
  1676. int sdio_pio_enable_interrupt(struct sdio_func *func)
  1677. {
  1678. unsigned char raw_val;
  1679. int err_ret = 0;
  1680. raw_val = sdio_f0_readb(func, 0x04, &err_ret);
  1681. if (err_ret) {
  1682. LOGPRT(LOG_ERR, "%s %d: read 0x04 err ret= %d\n", __func__,
  1683. __LINE__, err_ret);
  1684. goto err_out;
  1685. }
  1686. LOGPRT(LOG_DEBUG, "%s %d: read addr(0x04) 0x%x\n", __func__, __LINE__,
  1687. raw_val);
  1688. if (raw_val & (0x1 << 1)) {
  1689. LOGPRT(LOG_DEBUG,
  1690. "%s %d: The interrupt of pio-based function have been enabled\n",
  1691. __func__, __LINE__);
  1692. return 0;
  1693. }
  1694. raw_val |= (0x1 << 1); /*for PIO Only Function number change t0 "1" */
  1695. /*raw_val = 3; */
  1696. sdio_f0_writeb(func, raw_val, 0x04, &err_ret);
  1697. if (err_ret) {
  1698. LOGPRT(LOG_ERR, "%s %d: write 0x04 err ret= %d\n", __func__,
  1699. __LINE__, err_ret);
  1700. LOGPRT(LOG_ERR,
  1701. "%s %d: Enable pio-based function's interrupt failed\n",
  1702. __func__, __LINE__);
  1703. goto err_out;
  1704. } else {
  1705. LOGPRT(LOG_DEBUG,
  1706. "%s %d: The interrupt of pio-based function enabled success 0x%x\n",
  1707. __func__, __LINE__, raw_val);
  1708. raw_val = sdio_f0_readb(func, 0x04, &err_ret);
  1709. if (err_ret) {
  1710. LOGPRT(LOG_ERR, "%s %d: read 0x04 err ret= %d\n",
  1711. __func__, __LINE__, err_ret);
  1712. /*goto err_out; */
  1713. } else
  1714. LOGPRT(LOG_DEBUG, "%s %d: read CCCR success 0x%x\n",
  1715. __func__, __LINE__, raw_val);
  1716. return 0;
  1717. }
  1718. err_out:
  1719. return -1;
  1720. }
  1721. int sdio_pio_disable_interrupt(struct sdio_func *func)
  1722. {
  1723. unsigned char raw_val;
  1724. int err_ret = 0;
  1725. raw_val = sdio_f0_readb(func, 0x04, &err_ret);
  1726. if (err_ret) {
  1727. LOGPRT(LOG_ERR, "%s %d: read 0x04 err ret= %d\n", __func__,
  1728. __LINE__, err_ret);
  1729. goto err_out;
  1730. }
  1731. LOGPRT(LOG_DEBUG, "%s %d: read addr(0x04) 0x%x\n", __func__, __LINE__,
  1732. raw_val);
  1733. if (raw_val & (0x1 << 1)) {
  1734. LOGPRT(LOG_DEBUG,
  1735. "%s %d: The interrupt of pio-based function have been disabled\n",
  1736. __func__, __LINE__);
  1737. return 0;
  1738. }
  1739. raw_val &= ~(0x1 << 1); /*for PIO Only Function number change t0 "1" */
  1740. sdio_f0_writeb(func, raw_val, 0x04, &err_ret);
  1741. if (err_ret) {
  1742. LOGPRT(LOG_ERR, "%s %d: write 0x04 err ret= %d\n", __func__,
  1743. __LINE__, err_ret);
  1744. LOGPRT(LOG_ERR,
  1745. "%s %d: Disable pio-based function's interrupt failed\n",
  1746. __func__, __LINE__);
  1747. goto err_out;
  1748. } else {
  1749. LOGPRT(LOG_DEBUG,
  1750. "%s %d: The interrupt of pio-based function disabled success (0x%x)\n",
  1751. __func__, __LINE__, raw_val);
  1752. raw_val = sdio_f0_readb(func, 0x04, &err_ret);
  1753. if (err_ret) {
  1754. LOGPRT(LOG_ERR, "%s %d: read 0x04 err ret= %d\n",
  1755. __func__, __LINE__, err_ret);
  1756. /*goto err_out; */
  1757. } else
  1758. LOGPRT(LOG_DEBUG, "%s %d: read CCCR success 0x%x\n",
  1759. __func__, __LINE__, raw_val);
  1760. return 0;
  1761. }
  1762. err_out:
  1763. return -1;
  1764. }
  1765. void loopback_to_c2k(struct work_struct *work)
  1766. {
  1767. /*int ret = 0; */
  1768. struct sdio_modem *modem =
  1769. container_of(work, struct sdio_modem, loopback_work);
  1770. char *buf = NULL;
  1771. unsigned int len = 0;
  1772. /*int cnt = 0; */
  1773. /*unsigned int timeout = 500; */
  1774. struct sdio_msg_head *head = NULL;
  1775. struct sdio_msg_head *head_orig = NULL;
  1776. int left = 0;
  1777. int todo = 0;
  1778. int transed = 0;
  1779. int write_len = 0;
  1780. LOGPRT(LOG_NOTICE, "%s %d loopback_to_c2k.\n", __func__, __LINE__);
  1781. if (!modem || !modem->as_packet) {
  1782. LOGPRT(LOG_ERR, "%s %d bad parameters.\n", __func__, __LINE__);
  1783. return;
  1784. }
  1785. buf = modem->as_packet->buffer;
  1786. len = modem->as_packet->size;
  1787. head = (struct sdio_msg_head *)modem->trans_buffer;
  1788. head_orig = (struct sdio_msg_head *)buf;
  1789. left = len;
  1790. /*printk("[C2K] loopback_to_c2k 1\n"); */
  1791. do {
  1792. todo = left;
  1793. /*printk("[C2K] loopback_to_c2k 2\n"); */
  1794. /*
  1795. if(down_interruptible(&modem->sem)){
  1796. LOGPRT(LOG_ERR, "%s %d down_interruptible failed.\n", __func__,__LINE__);
  1797. ret = -ERESTARTSYS;
  1798. goto down_sem_fail;
  1799. } */
  1800. atomic_set(&modem->as_packet->occupied, 1);
  1801. /*printk("[C2K] loopback_to_c2k 3\n"); */
  1802. if (todo > TRANSMIT_MAX_SIZE)
  1803. todo = TRANSMIT_MAX_SIZE;
  1804. head->start_flag = 0xFE;
  1805. head->chanInfo = head_orig->chanInfo;
  1806. head->tranHi = (todo & 0xFF00) >> 8;
  1807. head->tranLow = todo & 0xFF;
  1808. head->hw_head.len_hi =
  1809. ((todo + sizeof(struct sdio_msg_head)) & 0xFF00) >> 8;
  1810. head->hw_head.len_low =
  1811. (todo + sizeof(struct sdio_msg_head)) & 0xFF;
  1812. if (left > todo)
  1813. head->tranHi |= 0x20; /*to indicate there is data left, not whole packet */
  1814. memcpy(modem->trans_buffer + sizeof(struct sdio_msg_head),
  1815. buf + sizeof(struct sdio_msg_head) + transed, todo);
  1816. atomic_set(&modem->as_packet->occupied, 0);
  1817. write_len = (todo + sizeof(struct sdio_msg_head) + 3) & ~0x03; /*Round up to nearest multiple of 4 */
  1818. /*
  1819. printk("[C2K] loopback_to_c2k 4\n");
  1820. while (atomic_read(&modem->tx_fifo_cnt) < write_len) {
  1821. msleep(1);
  1822. cnt ++;
  1823. if (cnt > timeout) {
  1824. LOGPRT(LOG_ERR, "%s write_len=%d wait %dms for TX_FIFO_CNT timeout!\n",
  1825. __func__, write_len, timeout);
  1826. return;
  1827. }
  1828. } */
  1829. pr_debug("[C2K] write %d back to c2k\n", write_len);
  1830. /*for loop back */
  1831. modem_sdio_write(modem, SDIO_CTDR, modem->trans_buffer,
  1832. write_len);
  1833. /*atomic_sub(write_len, &modem->tx_fifo_cnt); */
  1834. left -= todo;
  1835. transed += todo;
  1836. /*up(&modem->sem); */
  1837. } while (left);
  1838. atomic_set(&modem->as_packet->occupied, 0);
  1839. /*head_err_out:*/
  1840. /*down_sem_fail:*/
  1841. /*down_out:*/
  1842. /*for compile warning */
  1843. return;
  1844. }
  1845. #endif
  1846. void exception_data_dump(const char *buf, unsigned int len)
  1847. {
  1848. const unsigned char *print_buf = (const unsigned char *)buf;
  1849. int i;
  1850. if (!buf || (len <= 0)) {
  1851. LOGPRT(LOG_ERR, "[MODEM SDIO] %s: Bad parameters!\n", __func__);
  1852. goto err_exit;
  1853. }
  1854. LOGPRT(LOG_INFO, "[MODEM SDIO] Exception data dump begin\n");
  1855. for (i = 0; i < len; i++) {
  1856. if (i % 16 == 0)
  1857. pr_debug(" ");
  1858. pr_debug("%02X-", *(print_buf + i));
  1859. if ((i + 1) % 16 == 0)
  1860. pr_debug("\n");
  1861. }
  1862. pr_debug("\n");
  1863. LOGPRT(LOG_INFO, "Exception data dump end\n");
  1864. err_exit:
  1865. return;
  1866. }
  1867. #define eint_read32(b, a) ioread32((void __iomem *)((b)+(a)))
  1868. #define CIRQ_BASE (0x10204000)
  1869. int dump_c2k_sdio_status(struct sdio_modem *modem)
  1870. {
  1871. int ret = 0;
  1872. /*union sdio_pio_int_sts_reg int_sts;*/
  1873. unsigned int con;
  1874. unsigned int eint_reg[][2] = {
  1875. /*address, value */
  1876. {0x0010, 0},
  1877. {0x0050, 0},
  1878. {0x0090, 0},
  1879. {0x00D0, 0},
  1880. {0x0110, 0},
  1881. {0x0150, 0},
  1882. {0x0190, 0},
  1883. {0x01D0, 0},
  1884. {0x0210, 0},
  1885. {0x0250, 0},
  1886. {0x0290, 0},
  1887. {0, 0}, /*the end */
  1888. };
  1889. void __iomem *eint_iobase = ioremap(CIRQ_BASE, 0x400);
  1890. LOGPRT(LOG_ERR, "%s: enter!!\n", __func__);
  1891. /*read CIRQ_CON 0x10204300 */
  1892. con = eint_read32(eint_iobase, 0x300);
  1893. if (con & 0x1) {
  1894. unsigned int i = 0;
  1895. while (eint_reg[i][0]) {
  1896. eint_reg[i][1] =
  1897. eint_read32(eint_iobase, eint_reg[i][0]);
  1898. LOGPRT(LOG_ERR, "eint reg[%x]=%x\n", eint_reg[i][0],
  1899. eint_reg[i][1]);
  1900. i++;
  1901. }
  1902. } else {
  1903. LOGPRT(LOG_ERR, "eint con reg =%x\n", con);
  1904. }
  1905. /*dump gic */
  1906. mt_irq_dump_status(262);
  1907. /*mt_eint_dump_status(78); */
  1908. if (modem->func == NULL) {
  1909. LOGPRT(LOG_ERR, "%s %d: no func is NULL!!\n", __func__,
  1910. __LINE__);
  1911. return -1;
  1912. }
  1913. /*
  1914. ret = sdio_func1_rd(modem->func, &int_sts, SDIO_CHISR, sizeof(sdio_pio_int_sts_reg));
  1915. if (ret){
  1916. LOGPRT(LOG_ERR, "%s %d: get interrupt status failed ret=%d\n", __func__, __LINE__, ret);
  1917. return ret;
  1918. }
  1919. LOGPRT(LOG_ERR, "%s %d: orig int(0x%x)\n", __func__, __LINE__,
  1920. int_sts.raw_val);
  1921. */
  1922. return ret;
  1923. }
  1924. /*Parse exception info received from md, and tranlate into AP side exception structure*/
  1925. static void sdio_md_exception(struct sdio_modem *md)
  1926. {
  1927. struct _ex_exception_log_t *ex_info;
  1928. int ee_type;
  1929. struct dump_debug_info *debug_info = &md->debug_info;
  1930. if (debug_info == NULL)
  1931. return;
  1932. ex_info = &md->ex_info;
  1933. memset(debug_info, 0, sizeof(struct dump_debug_info));
  1934. ee_type = ex_info->header.ex_type;
  1935. debug_info->type = ee_type;
  1936. if (*((char *)ex_info + CCCI_EXREC_OFFSET_OFFENDER) != 0xCC) {
  1937. memcpy(debug_info->fatal_error.offender,
  1938. (char *)ex_info + CCCI_EXREC_OFFSET_OFFENDER,
  1939. sizeof(debug_info->fatal_error.offender) - 1);
  1940. debug_info->fatal_error.offender[sizeof
  1941. (debug_info->
  1942. fatal_error.offender) - 1] =
  1943. '\0';
  1944. } else {
  1945. debug_info->fatal_error.offender[0] = '\0';
  1946. }
  1947. switch (ee_type) {
  1948. case MD_EX_TYPE_INVALID:
  1949. debug_info->name = "INVALID";
  1950. break;
  1951. case MD_EX_TYPE_UNDEF:
  1952. debug_info->name = "Fatal error (undefine)";
  1953. debug_info->fatal_error.err_code1 =
  1954. ex_info->content.fatalerr.error_code.code1;
  1955. debug_info->fatal_error.err_code2 =
  1956. ex_info->content.fatalerr.error_code.code2;
  1957. break;
  1958. case MD_EX_TYPE_SWI:
  1959. debug_info->name = "Fatal error (swi)";
  1960. debug_info->fatal_error.err_code1 =
  1961. ex_info->content.fatalerr.error_code.code1;
  1962. debug_info->fatal_error.err_code2 =
  1963. ex_info->content.fatalerr.error_code.code2;
  1964. break;
  1965. case MD_EX_TYPE_PREF_ABT:
  1966. debug_info->name = "Fatal error (prefetch abort)";
  1967. debug_info->fatal_error.err_code1 =
  1968. ex_info->content.fatalerr.error_code.code1;
  1969. debug_info->fatal_error.err_code2 =
  1970. ex_info->content.fatalerr.error_code.code2;
  1971. break;
  1972. case MD_EX_TYPE_DATA_ABT:
  1973. debug_info->name = "Fatal error (data abort)";
  1974. debug_info->fatal_error.err_code1 =
  1975. ex_info->content.fatalerr.error_code.code1;
  1976. debug_info->fatal_error.err_code2 =
  1977. ex_info->content.fatalerr.error_code.code2;
  1978. break;
  1979. case MD_EX_TYPE_ASSERT:
  1980. debug_info->name = "ASSERT";
  1981. snprintf(debug_info->assert.file_name,
  1982. sizeof(debug_info->assert.file_name),
  1983. ex_info->content.assert.filename);
  1984. debug_info->assert.line_num =
  1985. ex_info->content.assert.linenumber;
  1986. debug_info->assert.parameters[0] =
  1987. ex_info->content.assert.parameters[0];
  1988. debug_info->assert.parameters[1] =
  1989. ex_info->content.assert.parameters[1];
  1990. debug_info->assert.parameters[2] =
  1991. ex_info->content.assert.parameters[2];
  1992. break;
  1993. case MD_EX_TYPE_FATALERR_TASK:
  1994. debug_info->name = "Fatal error (task)";
  1995. debug_info->fatal_error.err_code1 =
  1996. ex_info->content.fatalerr.error_code.code1;
  1997. debug_info->fatal_error.err_code2 =
  1998. ex_info->content.fatalerr.error_code.code2;
  1999. break;
  2000. case MD_EX_TYPE_FATALERR_BUF:
  2001. debug_info->name = "Fatal error (buff)";
  2002. debug_info->fatal_error.err_code1 =
  2003. ex_info->content.fatalerr.error_code.code1;
  2004. debug_info->fatal_error.err_code2 =
  2005. ex_info->content.fatalerr.error_code.code2;
  2006. break;
  2007. case MD_EX_TYPE_LOCKUP:
  2008. debug_info->name = "Lockup";
  2009. break;
  2010. case MD_EX_TYPE_ASSERT_DUMP:
  2011. debug_info->name = "ASSERT DUMP";
  2012. snprintf(debug_info->assert.file_name,
  2013. sizeof(debug_info->assert.file_name),
  2014. ex_info->content.assert.filename);
  2015. debug_info->assert.line_num =
  2016. ex_info->content.assert.linenumber;
  2017. break;
  2018. case DSP_EX_TYPE_ASSERT:
  2019. debug_info->name = "MD DMD ASSERT";
  2020. snprintf(debug_info->dsp_assert.file_name,
  2021. sizeof(debug_info->dsp_assert.file_name),
  2022. ex_info->content.assert.filename);
  2023. debug_info->dsp_assert.line_num =
  2024. ex_info->content.assert.linenumber;
  2025. snprintf(debug_info->dsp_assert.execution_unit,
  2026. sizeof(debug_info->dsp_assert.execution_unit),
  2027. ex_info->envinfo.execution_unit);
  2028. debug_info->dsp_assert.parameters[0] =
  2029. ex_info->content.assert.parameters[0];
  2030. debug_info->dsp_assert.parameters[1] =
  2031. ex_info->content.assert.parameters[1];
  2032. debug_info->dsp_assert.parameters[2] =
  2033. ex_info->content.assert.parameters[2];
  2034. break;
  2035. case DSP_EX_TYPE_EXCEPTION:
  2036. debug_info->name = "MD DMD Exception";
  2037. snprintf(debug_info->dsp_exception.execution_unit,
  2038. sizeof(debug_info->dsp_exception.execution_unit),
  2039. ex_info->envinfo.execution_unit);
  2040. debug_info->dsp_exception.code1 =
  2041. ex_info->content.fatalerr.error_code.code1;
  2042. break;
  2043. case DSP_EX_FATAL_ERROR:
  2044. debug_info->name = "MD DMD FATAL ERROR";
  2045. snprintf(debug_info->dsp_fatal_err.execution_unit,
  2046. sizeof(debug_info->dsp_fatal_err.execution_unit),
  2047. ex_info->envinfo.execution_unit);
  2048. debug_info->dsp_fatal_err.err_code[0] =
  2049. ex_info->content.fatalerr.error_code.code1;
  2050. debug_info->dsp_fatal_err.err_code[1] =
  2051. ex_info->content.fatalerr.error_code.code2;
  2052. break;
  2053. case CC_MD1_EXCEPTION:
  2054. debug_info->name = "Fatal error (LTE_EXP)";
  2055. debug_info->fatal_error.err_code1 =
  2056. ex_info->content.fatalerr.error_code.code1;
  2057. debug_info->fatal_error.err_code2 =
  2058. ex_info->content.fatalerr.error_code.code2;
  2059. break;
  2060. default:
  2061. debug_info->name = "UNKNOWN Exception";
  2062. break;
  2063. }
  2064. debug_info->ext_mem = ex_info;
  2065. debug_info->ext_size = sizeof(struct _ex_exception_log_t);
  2066. }
  2067. static int modem_exception_handler(struct sdio_modem *modem)
  2068. {
  2069. unsigned int excp_msg_len = 0;
  2070. /*u32 *msg_ptr = NULL; */
  2071. /*ccci_msg_t *ccci_msg = NULL; */
  2072. struct dump_debug_info *debug_info = NULL;
  2073. char ex_info[EE_BUF_LEN] = ""; /*attention, be careful with string length! */
  2074. int db_opt = DB_OPT_DEFAULT;
  2075. char buff[AED_STR_LEN];
  2076. struct _exception_msg *excp_msg = NULL;
  2077. unsigned long flags;
  2078. /*int show_aee = 1; */
  2079. excp_msg_len = calc_payload_len(&modem->msg->head, NULL);
  2080. /*prepare for send ack back to modem */
  2081. excp_msg_len =
  2082. (excp_msg_len + sizeof(struct sdio_msg_head) + 3) & ~0x03;
  2083. excp_msg = (struct _exception_msg *)(&modem->msg->buffer[0]);
  2084. spin_lock_irqsave(&modem->status_lock, flags);
  2085. modem->status = MD_EXCEPTION_ONGOING;
  2086. spin_unlock_irqrestore(&modem->status_lock, flags);
  2087. /*md will not response to any interrupt when EE happened, so make sure 4-line and data ack are disabled. */
  2088. modem->cbp_data->ipc_enable = false;
  2089. modem->cbp_data->data_ack_enable = false;
  2090. if (excp_msg->ccci_head.data1 == C2K_MD_EX) {
  2091. if (excp_msg->ccci_head.reserved == C2K_MD_EX_CHK_ID) {
  2092. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  2093. del_timer(&modem->force_assert_timer);
  2094. #endif
  2095. LOGPRT(LOG_INFO, "MD_EX received\n");
  2096. dump_c2k_iram();
  2097. } else {
  2098. LOGPRT(LOG_INFO, "Invalid MD_EX received\n");
  2099. }
  2100. excp_msg->ccci_head.channel = CCCI_CONTROL_TX_CH;
  2101. modem_sdio_write(modem, SDIO_WRITE_ADDR, modem->msg, excp_msg_len); /*MD_EX_ACK */
  2102. } else if (excp_msg->ccci_head.data1 == C2K_MD_EX_REC_OK) {
  2103. if (excp_msg->ccci_head.reserved == C2K_MD_EX_REC_OK_CHK_ID)
  2104. LOGPRT(LOG_INFO, "MD_EX_OK received\n");
  2105. else
  2106. LOGPRT(LOG_INFO, "Invalid MD_EX_OK received\n");
  2107. exception_data_dump(excp_msg->buffer,
  2108. excp_msg_len -
  2109. sizeof(struct sdio_msg_head) -
  2110. sizeof(struct _ccci_msg));
  2111. /*parse 512B exception data */
  2112. memcpy(&modem->ex_info, &excp_msg->buffer,
  2113. sizeof(struct _ex_exception_log_t));
  2114. sdio_md_exception(modem);
  2115. debug_info = &modem->debug_info;
  2116. switch (debug_info->type) {
  2117. case MD_EX_TYPE_ASSERT_DUMP:
  2118. case MD_EX_TYPE_ASSERT:
  2119. LOGPRT(LOG_INFO, "filename = %s\n",
  2120. debug_info->assert.file_name);
  2121. LOGPRT(LOG_INFO, "line = %d\n",
  2122. debug_info->assert.line_num);
  2123. LOGPRT(LOG_INFO, "para0 = %d, para1 = %d, para2 = %d\n",
  2124. debug_info->assert.parameters[0],
  2125. debug_info->assert.parameters[1],
  2126. debug_info->assert.parameters[2]);
  2127. snprintf(ex_info, EE_BUF_LEN,
  2128. "\n[%s] file:%s line:%d\np1:0x%08x\np2:0x%08x\np3:0x%08x\n",
  2129. debug_info->name, debug_info->assert.file_name,
  2130. debug_info->assert.line_num,
  2131. debug_info->assert.parameters[0],
  2132. debug_info->assert.parameters[1],
  2133. debug_info->assert.parameters[2]);
  2134. break;
  2135. case MD_EX_TYPE_UNDEF:
  2136. case MD_EX_TYPE_SWI:
  2137. case MD_EX_TYPE_PREF_ABT:
  2138. case MD_EX_TYPE_DATA_ABT:
  2139. case MD_EX_TYPE_FATALERR_BUF:
  2140. case MD_EX_TYPE_FATALERR_TASK:
  2141. case CC_MD1_EXCEPTION:
  2142. LOGPRT(LOG_INFO, "fatal error code 1 = %d\n",
  2143. debug_info->fatal_error.err_code1);
  2144. LOGPRT(LOG_INFO, "fatal error code 2 = %d\n",
  2145. debug_info->fatal_error.err_code2);
  2146. snprintf(ex_info, EE_BUF_LEN,
  2147. "\n[%s] err_code1:%d err_code2:%d\n",
  2148. debug_info->name,
  2149. debug_info->fatal_error.err_code1,
  2150. debug_info->fatal_error.err_code2);
  2151. break;
  2152. case MD_EX_TYPE_EMI_CHECK:
  2153. LOGPRT(LOG_INFO,
  2154. "md_emi_check: %08X, %08X, %02d, %08X\n",
  2155. debug_info->data.data0, debug_info->data.data1,
  2156. debug_info->data.channel,
  2157. debug_info->data.reserved);
  2158. snprintf(ex_info, EE_BUF_LEN,
  2159. "\n[emi_chk] %08X, %08X, %02d, %08X\n",
  2160. debug_info->data.data0, debug_info->data.data1,
  2161. debug_info->data.channel,
  2162. debug_info->data.reserved);
  2163. break;
  2164. case DSP_EX_TYPE_ASSERT:
  2165. LOGPRT(LOG_INFO, "filename = %s\n",
  2166. debug_info->dsp_assert.file_name);
  2167. LOGPRT(LOG_INFO, "line = %d\n",
  2168. debug_info->dsp_assert.line_num);
  2169. LOGPRT(LOG_INFO, "exec unit = %s\n",
  2170. debug_info->dsp_assert.execution_unit);
  2171. LOGPRT(LOG_INFO, "para0 = %d, para1 = %d, para2 = %d\n",
  2172. debug_info->dsp_assert.parameters[0],
  2173. debug_info->dsp_assert.parameters[1],
  2174. debug_info->dsp_assert.parameters[2]);
  2175. snprintf(ex_info, EE_BUF_LEN,
  2176. "\n[%s] file:%s line:%d\nexec:%s\np1:%d\np2:%d\np3:%d\n",
  2177. debug_info->name, debug_info->assert.file_name,
  2178. debug_info->assert.line_num,
  2179. debug_info->dsp_assert.execution_unit,
  2180. debug_info->dsp_assert.parameters[0],
  2181. debug_info->dsp_assert.parameters[1],
  2182. debug_info->dsp_assert.parameters[2]);
  2183. break;
  2184. case DSP_EX_TYPE_EXCEPTION:
  2185. LOGPRT(LOG_INFO, "exec unit = %s, code1:0x%08x\n",
  2186. debug_info->dsp_exception.execution_unit,
  2187. debug_info->dsp_exception.code1);
  2188. snprintf(ex_info, EE_BUF_LEN,
  2189. "\n[%s] exec:%s code1:0x%08x\n",
  2190. debug_info->name,
  2191. debug_info->dsp_exception.execution_unit,
  2192. debug_info->dsp_exception.code1);
  2193. break;
  2194. case DSP_EX_FATAL_ERROR:
  2195. LOGPRT(LOG_INFO, "exec unit = %s\n",
  2196. debug_info->dsp_fatal_err.execution_unit);
  2197. LOGPRT(LOG_INFO,
  2198. "err_code0 = 0x%08x, err_code1 = 0x%08x\n",
  2199. debug_info->dsp_fatal_err.err_code[0],
  2200. debug_info->dsp_fatal_err.err_code[1]);
  2201. snprintf(ex_info, EE_BUF_LEN,
  2202. "\n[%s] exec:%s err_code1:0x%08x err_code2:0x%08x\n",
  2203. debug_info->name,
  2204. debug_info->dsp_fatal_err.execution_unit,
  2205. debug_info->dsp_fatal_err.err_code[0],
  2206. debug_info->dsp_fatal_err.err_code[1]);
  2207. break;
  2208. default: /*Only display exception name */
  2209. snprintf(ex_info, EE_BUF_LEN, "\n[%s]\n",
  2210. debug_info->name);
  2211. break;
  2212. }
  2213. snprintf(buff, AED_STR_LEN, "md3:%s%s", ex_info,
  2214. c2k_img_info_str);
  2215. #if defined CONFIG_MTK_AEE_FEATURE
  2216. if (debug_info->type == CC_MD1_EXCEPTION
  2217. && debug_info->fatal_error.err_code1 ==
  2218. MD_EX_LTE_FATAL_ERROR) {
  2219. LOGPRT(LOG_ERR, "LTE EE, no need to trigger aee\n");
  2220. } else {
  2221. aed_md_exception_api(NULL, 0, NULL, 0, buff, db_opt);
  2222. }
  2223. #endif
  2224. }
  2225. return 0;
  2226. }
  2227. #if 0
  2228. /*query modem func's pending irq flag*/
  2229. static int modem_irq_query(struct sdio_func *func, unsigned char *pendingirq)
  2230. {
  2231. int func_num = 0;
  2232. int ret = 0;
  2233. /*Hack to access Function-0 */
  2234. func_num = func->num;
  2235. func->num = 0;
  2236. *pendingirq = sdio_readb(func, SDIO_CCCR_INTx, &ret);
  2237. if (ret) {
  2238. LOGPRT(LOG_ERR, "%s %d: read SDIO_CCCR_INTx err ret= %d\n",
  2239. __func__, __LINE__, ret);
  2240. }
  2241. func->num = func_num;
  2242. return ret;
  2243. }
  2244. #endif
  2245. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  2246. static int sdio_modem_log_input(struct sdio_modem *modem, unsigned int index)
  2247. {
  2248. unsigned char *log_addr = NULL;
  2249. int read_ptr = 0, read_len = 0;
  2250. int ret = 0;
  2251. struct sdio_buf_in_packet *packet = NULL;
  2252. struct sdio_modem_port *port;
  2253. port = modem->port[MD_LOG_CH_ID - 1];
  2254. ret = check_port(port);
  2255. if (ret < 0) {
  2256. LOGPRT(LOG_ERR,
  2257. "%s %d: check port error\n", __func__, __LINE__);
  2258. return ret; /*goto out; */
  2259. }
  2260. memcpy(&modem->curr_log_blk,
  2261. modem->as_packet->buffer +
  2262. sizeof(struct sdio_msg_head), sizeof(modem->curr_log_blk));
  2263. LOGPRT(LOG_INFO, "logging in %x %x\n",
  2264. modem->curr_log_blk.address, modem->curr_log_blk.length);
  2265. modem->log_blk_stamp = sched_clock();
  2266. log_addr =
  2267. ioremap_nocache(md3_mem_base +
  2268. modem->curr_log_blk.address,
  2269. modem->curr_log_blk.length <
  2270. 16 ? 16 : modem->curr_log_blk.length);
  2271. if (port->inception) {
  2272. while (read_ptr < modem->curr_log_blk.length) {
  2273. read_len = modem->curr_log_blk.length - read_ptr;
  2274. read_len = read_len < 4096 ? read_len : 4096;
  2275. ret =
  2276. rawbulk_push_upstream_buffer
  2277. (MD_LOG_CH_ID - 1, log_addr + read_ptr, read_len);
  2278. if (ret > 0)
  2279. read_ptr += read_len;
  2280. else
  2281. mdelay(1);
  2282. }
  2283. } else {
  2284. while (read_ptr < modem->curr_log_blk.length) {
  2285. read_len = modem->curr_log_blk.length - read_ptr;
  2286. read_len = read_len < 4096 ? read_len : 4096;
  2287. retry_get_log_in_room:
  2288. mutex_lock(&port->sdio_buf_in_mutex);
  2289. port->sdio_buf_in_size += read_len;
  2290. if (port->sdio_buf_in_size > SDIO_BUF_IN_MAX_SIZE) {
  2291. port->sdio_buf_in_size -= read_len;
  2292. mutex_unlock(&port->sdio_buf_in_mutex);
  2293. msleep(20);
  2294. goto retry_get_log_in_room;
  2295. } else {
  2296. packet =
  2297. kzalloc(sizeof
  2298. (struct
  2299. sdio_buf_in_packet), GFP_KERNEL);
  2300. if (!packet) {
  2301. LOGPRT(LOG_ERR,
  2302. "%s %d: kzalloc packet error for log\n",
  2303. __func__, __LINE__);
  2304. port->sdio_buf_in_size -= read_len;
  2305. mutex_unlock(&port->sdio_buf_in_mutex);
  2306. msleep(20);
  2307. goto retry_get_log_in_room;
  2308. }
  2309. INIT_LIST_HEAD(&packet->node);
  2310. packet->size = read_len;
  2311. packet->o_size = packet->size;
  2312. packet->offset = 0;
  2313. packet->buffer =
  2314. kzalloc(packet->size, GFP_KERNEL);
  2315. if (!packet->buffer) {
  2316. LOGPRT(LOG_ERR,
  2317. "%s %d: kzalloc packet buffer error for log\n",
  2318. __func__, __LINE__);
  2319. port->sdio_buf_in_size -= read_len;
  2320. kfree(packet);
  2321. mutex_unlock(&port->sdio_buf_in_mutex);
  2322. msleep(20);
  2323. goto retry_get_log_in_room;
  2324. }
  2325. LOGPRT(LOG_INFO,
  2326. "logging copy from %p to %p\n",
  2327. (log_addr + read_ptr), packet->buffer);
  2328. memcpy(packet->buffer,
  2329. log_addr + read_ptr, packet->size);
  2330. list_add_tail
  2331. (&packet->node, &port->sdio_buf_in_list);
  2332. port->sdio_buf_in_num++;
  2333. port->sdio_buf_in = 1;
  2334. LOGPRT(LOG_DEBUG,
  2335. "%s %d: ttySDIO%u data buffered %d for log!\n",
  2336. __func__, __LINE__, index, packet->size);
  2337. mutex_unlock(&port->sdio_buf_in_mutex);
  2338. wake_up_all(&port->rx_wq);
  2339. }
  2340. read_ptr += read_len;
  2341. }
  2342. }
  2343. schedule_work(&modem->smem_read_done_work);
  2344. iounmap(log_addr);
  2345. return 0;
  2346. }
  2347. static int sdio_modem_char_input(struct sdio_modem *modem,
  2348. unsigned int index,
  2349. unsigned int payload_offset)
  2350. {
  2351. int ret = 0;
  2352. struct sdio_buf_in_packet *packet = NULL;
  2353. unsigned int retry_cnt = 0;
  2354. struct sdio_modem_port *port;
  2355. port = modem->port[index];
  2356. retry_get_buf_in_room:
  2357. mutex_lock(&port->sdio_buf_in_mutex);
  2358. port->sdio_buf_in_size += (modem->data_length - payload_offset);
  2359. if (port->sdio_buf_in_size > SDIO_BUF_IN_MAX_SIZE) {
  2360. if (modem->status ==
  2361. MD_EXCEPTION || modem->status == MD_EXCEPTION_ONGOING) {
  2362. port->sdio_buf_in_size
  2363. -= (modem->data_length - payload_offset);
  2364. mutex_unlock(&port->sdio_buf_in_mutex);
  2365. msleep(20);
  2366. if (retry_cnt % 20 == 0)
  2367. LOGPRT
  2368. (LOG_INFO,
  2369. "retry_get_buf_in_room: port%u, retry_cnt=%u\n",
  2370. index, retry_cnt);
  2371. retry_cnt++;
  2372. goto retry_get_buf_in_room;
  2373. } else {
  2374. port->sdio_buf_in_size
  2375. -= (modem->data_length - payload_offset);
  2376. mutex_unlock(&port->sdio_buf_in_mutex);
  2377. pr_debug
  2378. ("[C2K] ttySDIO%u data buffer overrun %d!\n",
  2379. index, (modem->data_length - payload_offset));
  2380. }
  2381. } else {
  2382. packet = kzalloc(sizeof(struct sdio_buf_in_packet), GFP_KERNEL);
  2383. if (!packet) {
  2384. LOGPRT(LOG_ERR,
  2385. "%s %d: kzalloc packet error\n",
  2386. __func__, __LINE__);
  2387. port->sdio_buf_in_size
  2388. -= (modem->data_length - payload_offset);
  2389. ret = -ENOMEM;
  2390. mutex_unlock(&port->sdio_buf_in_mutex);
  2391. return ret; /*goto wait_ack; */
  2392. }
  2393. INIT_LIST_HEAD(&packet->node);
  2394. packet->size = modem->data_length - payload_offset;
  2395. #if ENABLE_CHAR_DEV
  2396. packet->o_size = packet->size;
  2397. packet->offset = 0;
  2398. #endif
  2399. packet->buffer = kzalloc(packet->size, GFP_KERNEL);
  2400. if (!packet->buffer) {
  2401. LOGPRT(LOG_ERR,
  2402. "%s %d: kzalloc packet buffer error\n",
  2403. __func__, __LINE__);
  2404. port->sdio_buf_in_size
  2405. -= (modem->data_length - payload_offset);
  2406. ret = -ENOMEM;
  2407. kfree(packet);
  2408. mutex_unlock(&port->sdio_buf_in_mutex);
  2409. return ret; /*goto wait_ack; */
  2410. }
  2411. memcpy(packet->buffer,
  2412. (modem->as_packet->buffer + sizeof(struct sdio_msg_head)
  2413. + payload_offset), packet->size);
  2414. #if ENABLE_CHAR_DEV
  2415. list_add_tail(&packet->node, &port->sdio_buf_in_list);
  2416. port->sdio_buf_in_num++;
  2417. #else
  2418. if (port->sdio_buf_in_num < port->sdio_buf_in_max_num) {
  2419. list_add_tail(&packet->node, &port->sdio_buf_in_list);
  2420. port->sdio_buf_in_num++;
  2421. } else {
  2422. struct
  2423. sdio_buf_in_packet
  2424. *old_packet;
  2425. old_packet = list_first_entry(&port->sdio_buf_in_list, struct
  2426. sdio_buf_in_packet, node);
  2427. list_del(&old_packet->node);
  2428. if (old_packet) {
  2429. port->sdio_buf_in_size -= old_packet->size;
  2430. kfree(old_packet->buffer);
  2431. kfree(old_packet);
  2432. }
  2433. list_add_tail(&packet->node, &port->sdio_buf_in_list);
  2434. }
  2435. #endif
  2436. port->sdio_buf_in = 1;
  2437. LOGPRT(LOG_DEBUG,
  2438. "%s %d: ttySDIO%d data buffered %d!\n",
  2439. __func__, __LINE__, index, packet->size);
  2440. mutex_unlock(&port->sdio_buf_in_mutex);
  2441. #if ENABLE_CHAR_DEV
  2442. wake_up_all(&port->rx_wq);
  2443. #endif
  2444. }
  2445. return 0;
  2446. }
  2447. #if !ENABLE_CHAR_DEV
  2448. static int sdio_modem_tty_input(struct sdio_modem *modem, unsigned int index)
  2449. {
  2450. int ret = 0;
  2451. struct sdio_modem_port *port;
  2452. port = modem->port[index];
  2453. if (port->sdio_buf_in == 1) {
  2454. /*make sure data in list bufeer had been pushed to tty buffer */
  2455. mutex_lock(&port->sdio_buf_in_mutex);
  2456. mutex_unlock(&port->sdio_buf_in_mutex);
  2457. }
  2458. retry_get_tty_room:
  2459. ret =
  2460. tty_buffer_request_room
  2461. (&port->port, modem->data_length - payload_offset);
  2462. if (ret < (modem->data_length - payload_offset)) {
  2463. if (modem->status ==
  2464. MD_EXCEPTION || modem->status == MD_EXCEPTION_ONGOING) {
  2465. msleep(20);
  2466. goto retry_get_tty_room;
  2467. } else
  2468. LOGPRT(LOG_ERR,
  2469. "%s %d: ttySDIO%d no room in tty rx buffer!(md status %d)\n",
  2470. __func__, __LINE__, index, modem->status);
  2471. } else {
  2472. ret =
  2473. tty_insert_flip_string
  2474. (&port->port,
  2475. (modem->as_packet->buffer
  2476. + payload_offset +
  2477. sizeof(struct
  2478. sdio_msg_head)),
  2479. (modem->data_length - payload_offset));
  2480. if (ret < (modem->data_length - payload_offset)) {
  2481. LOGPRT(LOG_ERR,
  2482. "%s %d: ttySDIO%d couldn't insert all characters (TTY is full?)!\n",
  2483. __func__, __LINE__, index);
  2484. } else {
  2485. tty_flip_buffer_push(&port->port);
  2486. }
  2487. }
  2488. return 0;
  2489. }
  2490. #endif
  2491. static void sdio_pio_intr_handler(struct sdio_func *func)
  2492. {
  2493. unsigned int pure_int;
  2494. static int interrupt_cnt;
  2495. struct sdio_modem *modem;
  2496. struct sdio_modem_port *port;
  2497. /*unsigned char reg = 0; */
  2498. /*int bytecnt = 0; */
  2499. int ret = 0;
  2500. /*int iir =0; */
  2501. /*int readcnt = 0; */
  2502. struct tty_struct *tty;
  2503. unsigned char index = 0;
  2504. unsigned char payload_offset = 0;
  2505. /*struct sdio_buf_in_packet *packet = NULL; */
  2506. static int keep_skb;
  2507. /*unsigned int excp_msg_len = 0; */
  2508. /*u32 *msg_ptr = NULL; */
  2509. /*DEBUG_INFO_T *debug_info = NULL; */
  2510. /*char ex_info[EE_BUF_LEN]=""; attention, be careful with string length! */
  2511. /*int db_opt = DB_OPT_DEFAULT; */
  2512. /*char buff[AED_STR_LEN]; */
  2513. int crplr = 0;
  2514. /*unsigned char pending = 0; */
  2515. unsigned int hw_len;
  2516. int raw_val;
  2517. static struct sdio_msg_head *msg_head;
  2518. static int throughput_count;
  2519. static int total_copy;
  2520. static int keep_recv;
  2521. static int dump_exp_data = 1;
  2522. union sdio_pio_int_sts_reg *int_sts;
  2523. union sdio_pio_int_mask_reg *int_mask;
  2524. interrupt_cnt++;
  2525. LOGPRT(LOG_DEBUG, "%s enter %d times...\n", __func__, interrupt_cnt);
  2526. /*ret = modem_irq_query(func,&pending);
  2527. if (ret) {
  2528. LOGPRT(LOG_ERR, "read SDIO_CCCR_INTx err ret= %d\n", __func__,__LINE__,ret);
  2529. goto err_out;
  2530. }
  2531. if((pending & SDIO_FUNC_1) ==0){
  2532. LOGPRT(LOG_NOTICE2, "pending=%d ret= %d\n", pending,ret);
  2533. goto out;
  2534. }
  2535. */
  2536. modem = sdio_get_drvdata(func);
  2537. int_sts = &modem->int_sts;
  2538. int_mask = &modem->int_mask;
  2539. sdio_pio_disable_interrupt(func);
  2540. ret = sdio_func1_rd(func, &raw_val, SDIO_CHLPCR, sizeof(raw_val));
  2541. if (ret) {
  2542. LOGPRT(LOG_ERR, "%s %d: read SDIO_CHLPCR failed ret=%d\n",
  2543. __func__, __LINE__, ret);
  2544. } else
  2545. LOGPRT(LOG_DEBUG, "%s %d: SDIO_CHLPCR(0x%x)\n", __func__,
  2546. __LINE__, raw_val);
  2547. ret = sdio_func1_rd(func, &raw_val, SDIO_CHIER, sizeof(raw_val));
  2548. if (ret) {
  2549. LOGPRT(LOG_ERR, "%s %d: read SDIO_CHLPCR failed ret=%d\n",
  2550. __func__, __LINE__, ret);
  2551. } else
  2552. LOGPRT(LOG_DEBUG, "%s %d: SDIO_CHIER(0x%x)\n", __func__,
  2553. __LINE__, raw_val);
  2554. /*for (;;) { */
  2555. ret =
  2556. sdio_func1_rd(func, int_sts, SDIO_CHISR,
  2557. sizeof(union sdio_pio_int_sts_reg));
  2558. if (ret) {
  2559. LOGPRT(LOG_ERR, "%s %d: get interrupt status failed ret=%d\n",
  2560. __func__, __LINE__, ret);
  2561. goto end;
  2562. }
  2563. LOGPRT(LOG_DEBUG, "%s %d: orig int(0x%x)\n", __func__, __LINE__,
  2564. int_sts->raw_val);
  2565. pure_int =
  2566. int_sts->raw_val & (int_mask->raw_val | SDIO_CHISR_TX_CMPLT_CNT);
  2567. LOGPRT(LOG_DEBUG, "%s %d: pure_int(0x%x)\n", __func__, __LINE__,
  2568. pure_int);
  2569. if (!pure_int)
  2570. goto end;
  2571. if (modem->int_clr_ctl == SDIO_INT_CTL_W1C) {
  2572. ret =
  2573. sdio_func1_wr(func, SDIO_CHISR, &pure_int,
  2574. sizeof(union sdio_pio_int_sts_reg));
  2575. if (ret) {
  2576. LOGPRT(LOG_ERR,
  2577. "%s %d: write SDIO_CHISR failed ret=%d\n",
  2578. __func__, __LINE__, ret);
  2579. }
  2580. }
  2581. if (pure_int & SDIO_CHISR_FW_OWN_BACK)
  2582. modem->fw_own = 0;
  2583. if (pure_int & SDIO_CHISR_TX_EMPTY) {
  2584. LOGPRT(LOG_DEBUG, "got tx done\n");
  2585. #ifdef TX_DONE_TRACE
  2586. del_timer(&timer_wait_tx_done);
  2587. #endif
  2588. #if USE_CCIF_INTR
  2589. dump_ccif();
  2590. #endif
  2591. /*Can do Tx */
  2592. atomic_set(&modem->tx_fifo_cnt, TX_FIFO_SZ);
  2593. wake_up(&modem->wait_tx_done_q);
  2594. }
  2595. if (pure_int & SDIO_CHISR_TX_UNDER_THOLD) {
  2596. /*Can do Tx */
  2597. atomic_set(&modem->tx_fifo_cnt, TX_FIFO_SZ - DEFAULT_TX_THOLD);
  2598. }
  2599. if (pure_int & SDIO_CHISR_TX_OVERFLOW) {
  2600. /*g_tx_overflow_sts = 1; */
  2601. /*Error!!!! */
  2602. LOGPRT(LOG_ERR,
  2603. "!!!! sdio pio function got TX_OVERFLOW interrupt !!!!\n");
  2604. }
  2605. if (pure_int & SDIO_CHISR_RX_RDY) {
  2606. LOGPRT(LOG_DEBUG, "%s %d: rx ready\n", __func__, __LINE__);
  2607. /*Check CHISR.RX_PKT_LEN == CRPLR.RX_PKT_LEN */
  2608. ret = sdio_func1_rd(func, &crplr, SDIO_CRPLR, sizeof(crplr));
  2609. if (ret) {
  2610. LOGPRT(LOG_ERR,
  2611. "%s %d: read Rx Packet Length Register failed ret=%d\n",
  2612. __func__, __LINE__, ret);
  2613. } else {
  2614. if (((crplr & SDIO_CRPLR_RX_PKT_LEN) >> 16) !=
  2615. int_sts->u.rx_pkt_len) {
  2616. LOGPRT(LOG_ERR,
  2617. "!!!! CHISR.RX_PKT_LEN(%d) != CRPLR.RX_PKT_LEN(%d) !!!!\n",
  2618. int_sts->u.rx_pkt_len,
  2619. (crplr & SDIO_CRPLR_RX_PKT_LEN) >> 16);
  2620. }
  2621. LOGPRT(LOG_DEBUG, "rx pkt len (%d)",
  2622. int_sts->u.rx_pkt_len);
  2623. }
  2624. modem->msg->head.start_flag = 0;
  2625. modem->msg->head.chanInfo = 0;
  2626. modem->msg->head.tranHi = 0;
  2627. modem->msg->head.tranLow = 0;
  2628. memset(modem->msg->buffer, 0, sizeof(modem->msg->buffer));
  2629. if (modem->cbp_data->data_ack_enable) {
  2630. atomic_set(&modem->cbp_data->cbp_data_ack->state,
  2631. MODEM_ST_TX_RX);
  2632. }
  2633. if (0 ==
  2634. sdio_pio_rx_pkt(func, (char *)modem->msg,
  2635. int_sts->u.rx_pkt_len)) {
  2636. sdio_rx_cnt++;
  2637. total_copy += int_sts->u.rx_pkt_len;
  2638. if (total_copy > SDIO_ASSEMBLE_MAX) {
  2639. LOGPRT(LOG_ERR,
  2640. "%s %d error: packet size too large.\n",
  2641. __func__, __LINE__);
  2642. total_copy = 0;
  2643. goto end;
  2644. }
  2645. }
  2646. if ((modem->msg->head.chanInfo == SDIO_AT_CHANNEL_NUM) ||
  2647. (modem->msg->head.chanInfo == SDIO_AT2_CHANNEL_NUM) ||
  2648. (modem->msg->head.chanInfo == EXCP_MSG_CH_ID) ||
  2649. (modem->msg->head.chanInfo == EXCP_CTRL_CH_ID) ||
  2650. (modem->msg->head.chanInfo == AGPS_CH_ID) ||
  2651. (modem->msg->head.chanInfo == SDIO_AT3_CHANNEL_NUM)) {
  2652. sdio_tx_rx_printk(modem->msg, 0);
  2653. }
  2654. if ((modem->status == MD_EXCEPTION
  2655. || modem->status == MD_EXCEPTION_ONGOING)) {
  2656. if (dump_exp_data
  2657. && modem->msg->head.chanInfo == EXCP_DATA_CH_ID) {
  2658. sdio_tx_rx_printk(modem->msg, 0);
  2659. dump_exp_data = 0;
  2660. }
  2661. /*make sure each crash file can be dumpped */
  2662. if (modem->msg->head.chanInfo == EXCP_MSG_CH_ID)
  2663. dump_exp_data = 1;
  2664. }
  2665. if (dump_exp_data == 0 && modem->status == MD_READY)
  2666. /*reset it after modem is ready */
  2667. dump_exp_data = 1;
  2668. /*index = modem->msg->head.chanInfo -1; */
  2669. /*port = modem->port[index]; */
  2670. hw_len =
  2671. (modem->msg->head.hw_head.len_hi << 8) +
  2672. modem->msg->head.hw_head.len_low;
  2673. LOGPRT(LOG_DEBUG, "%s: hw_len (%d)\n", __func__, hw_len);
  2674. if (!keep_recv) {
  2675. LOGPRT(LOG_DEBUG, "%s %d new packet\n", __func__,
  2676. __LINE__);
  2677. while (atomic_read(&modem->as_packet->occupied))
  2678. msleep(20);
  2679. LOGPRT(LOG_DEBUG, "%s %d as_packet available now\n",
  2680. __func__, __LINE__);
  2681. if (modem->msg->head.tranHi & MORE_DATA_FOLLOWING) {
  2682. LOGPRT(LOG_DEBUG,
  2683. "%s %d now can begin assemble...\n",
  2684. __func__, __LINE__);
  2685. keep_recv = 1;
  2686. }
  2687. msg_head =
  2688. (struct sdio_msg_head *)modem->as_packet->buffer;
  2689. msg_head->chanInfo = modem->msg->head.chanInfo;
  2690. msg_head->start_flag = 0xFE;
  2691. modem->as_packet->size = 0;
  2692. }
  2693. modem->data_length = (((modem->msg->head.tranHi & 0x0F) << 8) |
  2694. (modem->msg->head.tranLow & 0xFF));
  2695. payload_offset = (modem->msg->head.tranHi & 0xC0) >> 6;
  2696. modem->data_length -= payload_offset;
  2697. /*if (keep_recv){ */
  2698. memcpy(modem->as_packet->buffer + sizeof(struct sdio_msg_head) +
  2699. modem->as_packet->size,
  2700. modem->msg->buffer + payload_offset, modem->data_length);
  2701. modem->as_packet->size += modem->data_length;
  2702. if (!(modem->msg->head.tranHi & MORE_DATA_FOLLOWING)) {
  2703. LOGPRT(LOG_DEBUG, "No data following\n");
  2704. msg_head->tranHi =
  2705. (modem->as_packet->size & 0xFF00) >> 8;
  2706. msg_head->tranLow = modem->as_packet->size & 0xFF;
  2707. msg_head->hw_head.len_hi =
  2708. ((modem->as_packet->size +
  2709. sizeof(struct sdio_msg_head)) & 0xFF00) >> 8;
  2710. msg_head->hw_head.len_low =
  2711. (modem->as_packet->size +
  2712. sizeof(struct sdio_msg_head)) & 0xFF;
  2713. LOGPRT(LOG_DEBUG, "hw_len low(0x%x), hi(0x%x)\n",
  2714. msg_head->hw_head.len_low,
  2715. msg_head->hw_head.len_hi);
  2716. LOGPRT(LOG_DEBUG, "as_packet(0x%x, 0x%x)\n",
  2717. *modem->as_packet->buffer,
  2718. *(modem->as_packet->buffer + 1));
  2719. #if 1
  2720. /*Just for test */
  2721. if (modem->msg->head.chanInfo == CCMNI_AP_LOOPBACK_CH) {
  2722. if (!throughput_count) {
  2723. LOGPRT(LOG_INFO,
  2724. "C2K throughput test begin....\n");
  2725. }
  2726. throughput_count++;
  2727. if (throughput_count == 5000) {
  2728. throughput_count = 0;
  2729. LOGPRT(LOG_INFO,
  2730. "C2K throughput test end....\n");
  2731. }
  2732. schedule_work(&modem->loopback_work);
  2733. }
  2734. #endif
  2735. total_copy = 0;
  2736. keep_recv = 0;
  2737. if (msg_head->start_flag != 0xFE) {
  2738. LOGPRT(LOG_ERR,
  2739. "%s %d: start_flag != 0xFE and value is 0x%x, go out.\n",
  2740. __func__, __LINE__,
  2741. modem->msg->head.start_flag);
  2742. goto out;
  2743. }
  2744. if (modem->msg->head.chanInfo == EXCP_CTRL_CH_ID
  2745. && (modem->status == MD_EXCEPTION
  2746. || modem->status == MD_EXCEPTION_ONGOING))
  2747. modem_exception_handler(modem);
  2748. if ((modem->msg->head.chanInfo == EXCP_MSG_CH_ID)
  2749. || (modem->msg->head.chanInfo == EXCP_DATA_CH_ID)) {
  2750. LOGPRT(LOG_DEBUG,
  2751. "excp msg/data received ch[%d]\n",
  2752. modem->msg->head.chanInfo);
  2753. }
  2754. #if ENABLE_CCMNI
  2755. if ((modem->msg->head.chanInfo & 0x0F) == CCMNI_CH_ID) {
  2756. index = CCMNI_CH_ID - 1;
  2757. port = modem->port[index];
  2758. if (!port->inception) {
  2759. static struct sk_buff *skb;
  2760. static int total_copy;
  2761. unsigned int rx_ch;
  2762. unsigned int rx_len;
  2763. rx_len =
  2764. (((modem->msg->
  2765. head.tranHi & 0x0F) << 8) |
  2766. (modem->msg->head.tranLow & 0xFF));
  2767. rx_ch =
  2768. (modem->msg->
  2769. head.chanInfo & 0xF0) >> 4;
  2770. modem->msg->head.chanInfo &= 0x0F;
  2771. retry_get_skb:
  2772. if (!keep_skb || !skb) {
  2773. LOGPRT(LOG_DEBUG,
  2774. "%s %d request skb from kernel.\n",
  2775. __func__, __LINE__);
  2776. skb = dev_alloc_skb(1600);
  2777. total_copy = 0;
  2778. }
  2779. if (!skb) {
  2780. LOGPRT(LOG_ERR,
  2781. "%s %d retry.\n",
  2782. __func__, __LINE__);
  2783. msleep(20);
  2784. goto retry_get_skb;
  2785. }
  2786. LOGPRT(LOG_DEBUG, "%s %d got skb.\n",
  2787. __func__, __LINE__);
  2788. if (rx_len > 1600 || total_copy > 1600) {
  2789. LOGPRT(LOG_ERR,
  2790. "%s %d error: skb too large.\n",
  2791. __func__, __LINE__);
  2792. goto out;
  2793. }
  2794. memcpy(skb_put(skb, rx_len),
  2795. modem->as_packet->buffer +
  2796. sizeof(struct sdio_msg_head),
  2797. rx_len);
  2798. total_copy += rx_len;
  2799. keep_skb = 1;
  2800. /*the last packet of skb received */
  2801. if (!(modem->msg->head.tranHi & 0x20)) {
  2802. LOGPRT(LOG_DEBUG,
  2803. "%s: data to ccmni...\n",
  2804. __func__);
  2805. /* sdio_tx_rx_printk(skb, 0); */
  2806. keep_skb = 0;
  2807. ccmni_ops.rx_callback
  2808. (SDIO_MD_ID, rx_ch, skb,
  2809. NULL);
  2810. } else
  2811. LOGPRT(LOG_DEBUG,
  2812. "%s: data to ccmni pending 0x%x...\n",
  2813. __func__,
  2814. modem->msg->head.tranHi);
  2815. }
  2816. }
  2817. #endif
  2818. #if ENABLE_CHAR_DEV
  2819. if ((modem->msg->head.chanInfo & 0x0F) == MD_LOG2_CH_ID) {
  2820. ret = sdio_modem_log_input(modem, index);
  2821. if (unlikely(ret < 0))
  2822. goto out;
  2823. }
  2824. #endif
  2825. if (msg_head->chanInfo > 0
  2826. && msg_head->chanInfo < (SDIO_TTY_NR + 1)) {
  2827. /*pay attention to channel mapping with rawbulk in rawbulk_push_upstream_buffer() */
  2828. index = msg_head->chanInfo - 1;
  2829. /*
  2830. because we've already processed offset info when copy data to as_packet buffer.
  2831. so ignore it here.
  2832. */
  2833. /*payload_offset = ((msg_head->tranHi & 0xC0) >> 6); */
  2834. payload_offset = 0;
  2835. if (payload_offset) {
  2836. LOGPRT(LOG_DEBUG,
  2837. "%s %d: payload_offset = %d.\n",
  2838. __func__, __LINE__,
  2839. payload_offset);
  2840. }
  2841. /*
  2842. tranHi comes from as_packet size, no other info.
  2843. audio packet size may be up to 16KB, so we should & 0xFF but not 0x0F here.
  2844. */
  2845. modem->data_length =
  2846. (((msg_head->tranHi & 0xFF) << 8) |
  2847. (msg_head->tranLow & 0xFF));
  2848. if (modem->data_length == 0) {
  2849. LOGPRT(LOG_ERR,
  2850. "%s %d: data_length is 0\n",
  2851. __func__, __LINE__);
  2852. goto out;
  2853. }
  2854. port = modem->port[index];
  2855. ret = check_port(port);
  2856. if (ret < 0) {
  2857. LOGPRT(LOG_ERR,
  2858. "%s %d: check port error\n",
  2859. __func__, __LINE__);
  2860. goto out;
  2861. }
  2862. if (port->inception) {
  2863. rawbulk_push_upstream_buffer(index,
  2864. (modem->as_packet->buffer
  2865. +
  2866. sizeof
  2867. (struct
  2868. sdio_msg_head)
  2869. +
  2870. payload_offset),
  2871. (modem->data_length
  2872. -
  2873. payload_offset));
  2874. #if ENABLE_CCMNI
  2875. } else if (msg_head->chanInfo != CCMNI_CH_ID) {
  2876. #else
  2877. } else {
  2878. #endif
  2879. #if ENABLE_CHAR_DEV
  2880. tty = NULL;
  2881. #else
  2882. tty = tty_port_tty_get(&port->port);
  2883. #endif
  2884. if (!tty) {
  2885. ret =
  2886. sdio_modem_char_input
  2887. (modem, index,
  2888. payload_offset);
  2889. }
  2890. if (!tty && ret < 0)
  2891. goto wait_ack;
  2892. #if !ENABLE_CHAR_DEV
  2893. if (tty && modem->data_length)
  2894. sdio_modem_tty_input(modem,
  2895. index);
  2896. if (tty)
  2897. tty_kref_put(tty);
  2898. #endif
  2899. }
  2900. } else if (msg_head->chanInfo == 0) { /*control message analyze */
  2901. ctrl_msg_analyze(modem);
  2902. } else {
  2903. #if ENABLE_CCMNI
  2904. if ((modem->msg->head.chanInfo & 0x0F) !=
  2905. CCMNI_CH_ID) {
  2906. LOGPRT(LOG_ERR,
  2907. "%s %d: error chanInfo is %d, go out.\n",
  2908. __func__, __LINE__,
  2909. modem->msg->head.chanInfo);
  2910. goto out;
  2911. }
  2912. #else
  2913. LOGPRT(LOG_ERR,
  2914. "%s %d: error chanInfo is %d, go out.\n",
  2915. __func__, __LINE__,
  2916. modem->msg->head.chanInfo);
  2917. goto out;
  2918. #endif
  2919. }
  2920. }
  2921. wait_ack:
  2922. /*
  2923. if(modem->cbp_data->data_ack_enable){
  2924. modem->cbp_data->data_ack_wait_event(modem->cbp_data->cbp_data_ack);
  2925. } */
  2926. out:
  2927. LOGPRT(LOG_DEBUG, "%s %d: out.\n", __func__, __LINE__);
  2928. /*return; */
  2929. /*err_out: */
  2930. /*LOGPRT(LOG_ERR, "%s %d: let cbp die now.\n",__func__, __LINE__); */
  2931. /*modem_err_indication_usr(1); */
  2932. /*return; */
  2933. }
  2934. if (pure_int & SDIO_CHISR_FW_INT_INDICATOR) {
  2935. /*handle fw int */
  2936. /*mt_sdio_pio_handle_fw_intr(); */
  2937. }
  2938. /*} */
  2939. end:
  2940. sdio_pio_enable_interrupt(func);
  2941. #ifdef TX_DONE_TRACE
  2942. pr_debug("[C2K] intr handler exit....");
  2943. #endif
  2944. }
  2945. #else
  2946. /*
  2947. *This SDIO interrupt handler.
  2948. */
  2949. static void modem_sdio_irq(struct sdio_func *func)
  2950. {
  2951. struct sdio_modem *modem;
  2952. struct sdio_modem_port *port;
  2953. unsigned char reg = 0;
  2954. int bytecnt = 0;
  2955. int ret = 0;
  2956. int iir = 0;
  2957. int readcnt = 0;
  2958. struct tty_struct *tty;
  2959. unsigned char index = 0;
  2960. unsigned int payload_offset;
  2961. struct sdio_buf_in_packet *packet = NULL;
  2962. unsigned char pending = 0;
  2963. static int keep_skb;
  2964. /*get pending interrupt */
  2965. ret = modem_irq_query(func, &pending);
  2966. if (ret) {
  2967. LOGPRT(LOG_ERR, "%s %d: read SDIO_CCCR_INTx err ret= %d\n",
  2968. __func__, __LINE__, ret);
  2969. goto err_out;
  2970. }
  2971. if ((pending & SDIO_FUNC_1_IRQ) == 0) {
  2972. LOGPRT(LOG_NOTICE2, "pending=%d ret= %d\n", pending, ret);
  2973. goto out;
  2974. }
  2975. modem = sdio_get_drvdata(func);
  2976. do {
  2977. /*Reading the IIR register on the slave clears the interrupt. Since host and
  2978. slave run asynchronously, must ensure int bit is set before reading
  2979. transfer count register */
  2980. iir = sdio_readb(func, 0x04, &ret);
  2981. } while ((iir != 1) && (readcnt++ <= 10));
  2982. if (ret) {
  2983. LOGPRT(LOG_ERR, "%s %d: read iir err ret= %d\n", __func__,
  2984. __LINE__, ret);
  2985. goto err_out;
  2986. }
  2987. if (iir != 1) {
  2988. LOGPRT(LOG_ERR, "%s %d error iir value = %d!!!\n", __func__,
  2989. __LINE__, iir);
  2990. goto out;
  2991. }
  2992. /*Read byte count */
  2993. reg = sdio_readb(func, 0x08, &ret);
  2994. if (ret) {
  2995. LOGPRT(LOG_ERR, "%s %d: read data cnt err ret= %d\n", __func__,
  2996. __LINE__, ret);
  2997. goto err_out;
  2998. }
  2999. bytecnt = reg;
  3000. reg = sdio_readb(func, 0x09, &ret);
  3001. if (ret) {
  3002. LOGPRT(LOG_ERR, "%s %d: read data cnt ret= %d\n", __func__,
  3003. __LINE__, ret);
  3004. goto err_out;
  3005. }
  3006. bytecnt |= (reg << 8);
  3007. if (bytecnt == 0) {
  3008. LOGPRT(LOG_ERR, "%s %d error read size %d.\n", __func__,
  3009. __LINE__, bytecnt);
  3010. goto out;
  3011. }
  3012. modem->msg->head.start_flag = 0;
  3013. modem->msg->head.chanInfo = 0;
  3014. modem->msg->head.tranHi = 0;
  3015. modem->msg->head.tranLow = 0;
  3016. memset(modem->msg->buffer, 0, sizeof(modem->msg->buffer));
  3017. if (modem->cbp_data->data_ack_enable) {
  3018. atomic_set(&modem->cbp_data->cbp_data_ack->state,
  3019. MODEM_ST_TX_RX);
  3020. }
  3021. ret = sdio_readsb(func, modem->msg, 0x00, bytecnt);
  3022. if (ret) {
  3023. LOGPRT(LOG_ERR,
  3024. "%s %d: port%d sdio read with error code = %d, read bytecount = %d!!!\n",
  3025. __func__, __LINE__, modem->msg->head.chanInfo, ret,
  3026. bytecnt);
  3027. goto err_out;
  3028. }
  3029. if ((modem->msg->head.chanInfo == SDIO_AT_CHANNEL_NUM) ||
  3030. (modem->msg->head.chanInfo == SDIO_AT2_CHANNEL_NUM) ||
  3031. (modem->msg->head.chanInfo == SDIO_AT3_CHANNEL_NUM) ||
  3032. (sdio_log_level > LOG_NOTICE)) {
  3033. sdio_tx_rx_printk(modem->msg, 0);
  3034. }
  3035. /*sdio_tx_rx_printk(modem->msg, 0); */
  3036. if (modem->msg->head.start_flag != MSG_START_FLAG) {
  3037. LOGPRT(LOG_ERR,
  3038. "%s %d: start_flag != MSG_START_FLAG and value is 0x%x, go out.\n",
  3039. __func__, __LINE__, modem->msg->head.start_flag);
  3040. goto out;
  3041. }
  3042. if (modem->msg->head.chanInfo == EXCP_CTRL_CH_ID)
  3043. LOGPRT(LOG_DEBUG, "modem status[%d]\n", modem->status);
  3044. if (modem->msg->head.chanInfo == EXCP_CTRL_CH_ID
  3045. && (modem->status == MD_EXCEPTION
  3046. || modem->status == MD_EXCEPTION_ONGOING)) {
  3047. modem_exception_handler(modem);
  3048. }
  3049. if ((modem->msg->head.chanInfo == EXCP_MSG_CH_ID)
  3050. || (modem->msg->head.chanInfo == EXCP_DATA_CH_ID)) {
  3051. LOGPRT(LOG_DEBUG,
  3052. "[MODEM SDIO] excp msg/data received ch[%d]\n",
  3053. modem->msg->head.chanInfo);
  3054. }
  3055. #if ENABLE_CCMNI
  3056. if ((modem->msg->head.chanInfo & 0x0F) == CCMNI_CH_ID) {
  3057. static struct sk_buff *skb;
  3058. static int total_copy;
  3059. unsigned int rx_ch;
  3060. unsigned int rx_len = 0;
  3061. rx_len = (((modem->msg->head.tranHi & 0x0F) << 8) |
  3062. (modem->msg->head.tranLow & 0xFF));
  3063. rx_ch = (modem->msg->head.chanInfo & 0xF0) >> 4;
  3064. modem->msg->head.chanInfo &= 0x0F;
  3065. retry_get_skb:
  3066. if (!keep_skb || !skb) {
  3067. LOGPRT(LOG_INFO, "%s %d request skb from kernel.\n",
  3068. __func__, __LINE__);
  3069. skb = dev_alloc_skb(1600);
  3070. total_copy = 0;
  3071. }
  3072. if (!skb) {
  3073. LOGPRT(LOG_INFO, "%s %d retry.\n", __func__, __LINE__);
  3074. msleep(20);
  3075. goto retry_get_skb;
  3076. }
  3077. LOGPRT(LOG_INFO, "%s %d got skb.\n", __func__, __LINE__);
  3078. if (total_copy > 1600) {
  3079. LOGPRT(LOG_ERR, "%s %d error: skb too large.\n",
  3080. __func__, __LINE__);
  3081. goto out;
  3082. }
  3083. memcpy(skb_put(skb, rx_len), modem->msg->buffer, rx_len);
  3084. total_copy += rx_len;
  3085. keep_skb = 1;
  3086. if (!(modem->msg->head.tranHi & 0x20)) { /*the last packet of skb received */
  3087. LOGPRT(LOG_INFO, "%s: data to ccmni...\n", __func__);
  3088. /* sdio_tx_rx_printk(skb, 0); */
  3089. keep_skb = 0;
  3090. ccmni_ops.rx_callback(SDIO_MD_ID, rx_ch, skb, NULL);
  3091. } else
  3092. LOGPRT(LOG_INFO, "%s: data to ccmni pending 0x%x...\n",
  3093. __func__, modem->msg->head.tranHi);
  3094. }
  3095. #endif
  3096. if (modem->msg->head.chanInfo > 0
  3097. && modem->msg->head.chanInfo < (SDIO_TTY_NR + 1)) {
  3098. index = modem->msg->head.chanInfo - 1;
  3099. modem->data_length =
  3100. calc_payload_len(&modem->msg->head, &payload_offset);
  3101. if (modem->data_length == 0) {
  3102. LOGPRT(LOG_ERR, "%s %d: data_length is 0\n", __func__,
  3103. __LINE__);
  3104. goto out;
  3105. }
  3106. port = modem->port[index];
  3107. ret = check_port(port);
  3108. if (ret < 0) {
  3109. LOGPRT(LOG_ERR, "%s %d: check port error\n", __func__,
  3110. __LINE__);
  3111. goto out;
  3112. }
  3113. port->rx_count++;
  3114. if (port->inception) {
  3115. rawbulk_push_upstream_buffer(index,
  3116. (modem->msg->buffer +
  3117. payload_offset),
  3118. modem->data_length);
  3119. } else {
  3120. tty = tty_port_tty_get(&port->port);
  3121. if (!tty) {
  3122. LOGPRT(LOG_ERR, "tty is NULL");
  3123. mutex_lock(&port->sdio_buf_in_mutex);
  3124. port->sdio_buf_in_size += modem->data_length;
  3125. if (port->sdio_buf_in_size >
  3126. SDIO_BUF_IN_MAX_SIZE) {
  3127. port->sdio_buf_in_size -=
  3128. modem->data_length;
  3129. mutex_unlock(&port->sdio_buf_in_mutex);
  3130. LOGPRT(LOG_ERR,
  3131. "%s %d: ttySDIO%d data buffer overrun!\n",
  3132. __func__, __LINE__, index);
  3133. } else {
  3134. packet =
  3135. kzalloc(sizeof
  3136. (struct sdio_buf_in_packet),
  3137. GFP_KERNEL);
  3138. if (!packet) {
  3139. LOGPRT(LOG_ERR,
  3140. "%s %d: kzalloc packet error\n",
  3141. __func__, __LINE__);
  3142. ret = -ENOMEM;
  3143. mutex_unlock
  3144. (&port->sdio_buf_in_mutex);
  3145. goto wait_ack;
  3146. }
  3147. packet->size = modem->data_length;
  3148. packet->buffer =
  3149. kzalloc(packet->size, GFP_KERNEL);
  3150. if (!packet->buffer) {
  3151. LOGPRT(LOG_ERR,
  3152. "%s %d: kzalloc packet buffer error\n",
  3153. __func__, __LINE__);
  3154. ret = -ENOMEM;
  3155. kfree(packet);
  3156. mutex_unlock
  3157. (&port->sdio_buf_in_mutex);
  3158. goto wait_ack;
  3159. }
  3160. memcpy(packet->buffer,
  3161. (modem->msg->buffer +
  3162. payload_offset), packet->size);
  3163. if (port->sdio_buf_in_num <
  3164. port->sdio_buf_in_max_num) {
  3165. list_add_tail(&packet->node,
  3166. &port->sdio_buf_in_list);
  3167. port->sdio_buf_in_num++;
  3168. } else {
  3169. struct sdio_buf_in_packet
  3170. *old_packet = NULL;
  3171. old_packet =
  3172. list_first_entry
  3173. (&port->sdio_buf_in_list,
  3174. struct
  3175. sdio_buf_in_packet, node);
  3176. list_del(&old_packet->node);
  3177. /*if (old_packet) { */
  3178. port->sdio_buf_in_size
  3179. -= old_packet->size;
  3180. kfree(old_packet->buffer);
  3181. kfree(old_packet);
  3182. list_add_tail(&packet->node,
  3183. &port->sdio_buf_in_list);
  3184. }
  3185. port->sdio_buf_in = 1;
  3186. mutex_unlock(&port->sdio_buf_in_mutex);
  3187. LOGPRT(LOG_ERR,
  3188. "%s %d: ttySDIO%d data buffered!\n",
  3189. __func__, __LINE__, index);
  3190. }
  3191. }
  3192. if (tty && modem->data_length) {
  3193. if (port->sdio_buf_in == 1) {
  3194. /*make sure data in list buffer had been pushed to tty buffer */
  3195. mutex_lock(&port->sdio_buf_in_mutex);
  3196. mutex_unlock(&port->sdio_buf_in_mutex);
  3197. }
  3198. ret =
  3199. tty_buffer_request_room(&port->port,
  3200. modem->data_length);
  3201. if (ret < modem->data_length) {
  3202. LOGPRT(LOG_ERR,
  3203. "%s %d: ttySDIO%d no room in tty rx buffer!\n",
  3204. __func__, __LINE__, index);
  3205. } else {
  3206. ret =
  3207. tty_insert_flip_string(&port->port,
  3208. (modem->
  3209. msg->buffer
  3210. +
  3211. payload_offset),
  3212. modem->data_length);
  3213. if (ret < modem->data_length) {
  3214. LOGPRT(LOG_ERR,
  3215. "%s %d: ttySDIO%d couldn't insert all characters!\n",
  3216. __func__, __LINE__,
  3217. index);
  3218. } else {
  3219. tty_flip_buffer_push
  3220. (&port->port);
  3221. }
  3222. }
  3223. }
  3224. if (tty)
  3225. tty_kref_put(tty);
  3226. }
  3227. } else if (modem->msg->head.chanInfo == CTRL_CH_ID) { /*control message analyze */
  3228. ctrl_msg_analyze(modem);
  3229. } else {
  3230. LOGPRT(LOG_ERR, "%s %d: error chanInfo is %d, go out.\n",
  3231. __func__, __LINE__, modem->msg->head.chanInfo);
  3232. goto out;
  3233. }
  3234. wait_ack:
  3235. /*LOGPRT(LOG_ERR, "%s %d: port%d data ack before!\n", __func__, __LINE__, port->index); */
  3236. if (modem->cbp_data->data_ack_enable) {
  3237. modem->cbp_data->data_ack_wait_event(modem->
  3238. cbp_data->cbp_data_ack);
  3239. }
  3240. /*LOGPRT(LOG_ERR, "%s %d: port%d data ack after!\n", __func__, __LINE__, port->index); */
  3241. out:
  3242. return;
  3243. err_out:
  3244. LOGPRT(LOG_ERR, "%s %d: let cbp die now.\n", __func__, __LINE__);
  3245. modem_err_indication_usr(1);
  3246. }
  3247. #endif
  3248. static int func_enable_irq(struct sdio_func *func, int enable)
  3249. {
  3250. int func_num = 0;
  3251. u8 cccr = 0;
  3252. int ret = 0;
  3253. if (!func->card)
  3254. return -1;
  3255. /*Hack to access Function-0 */
  3256. func_num = func->num;
  3257. func->num = 0;
  3258. cccr = sdio_readb(func, SDIO_CCCR_IENx, &ret);
  3259. if (WARN_ON(ret))
  3260. goto set_func;
  3261. if (enable) {
  3262. /*Master interrupt enable ... */
  3263. cccr |= BIT(0);
  3264. /*... for our function */
  3265. cccr |= BIT(func_num);
  3266. } else {
  3267. /*Master interrupt enable ... */
  3268. cccr &= ~(BIT(0));
  3269. /*... for our function */
  3270. cccr &= ~(BIT(func_num));
  3271. }
  3272. sdio_writeb(func, cccr, SDIO_CCCR_IENx, &ret);
  3273. if (WARN_ON(ret))
  3274. goto set_func;
  3275. /*Restore the modem function number */
  3276. func->num = func_num;
  3277. return 0;
  3278. set_func:
  3279. func->num = func_num;
  3280. return ret;
  3281. }
  3282. static void modem_sdio_write(struct sdio_modem *modem, int addr,
  3283. void *buf, size_t len)
  3284. {
  3285. struct sdio_func *func = modem->func;
  3286. /*struct mmc_host *host = func->card->host; */
  3287. unsigned char *print_buf = NULL;
  3288. struct sdio_msg_head *msg_head = NULL;
  3289. #if PADDING_BY_BLOCK_SIZE
  3290. unsigned int block_cnt = 0;
  3291. unsigned int padding_len = 0;
  3292. int padding_index = 0;
  3293. char *pad_begin_ptr = NULL;
  3294. #endif
  3295. unsigned char ch_id;
  3296. unsigned char tport_id;
  3297. int err_flag = 0;
  3298. int ret;
  3299. int tx_ready = -1;
  3300. static int modem_fc_flag;
  3301. unsigned long flags;
  3302. if (buf) {
  3303. msg_head = (struct sdio_msg_head *)buf;
  3304. print_buf = (unsigned char *)buf;
  3305. }
  3306. ch_id = msg_head->chanInfo & 0x0F;
  3307. tport_id = ch_id - 1;
  3308. if (tport_id >= 0 && tport_id < SDIO_TTY_NR)
  3309. modem->port[tport_id]->tx_count++;
  3310. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  3311. if (ch_id == CTRL_CH_ID)
  3312. pr_debug("[C2K] before wait tx done\n");
  3313. spin_lock_irqsave(&modem->status_lock, flags);
  3314. if (modem->status == MD_OFF) {
  3315. spin_unlock_irqrestore(&modem->status_lock, flags);
  3316. LOGPRT(LOG_NOTICE, "c2k off now, ignore\n");
  3317. goto terminate;
  3318. }
  3319. spin_unlock_irqrestore(&modem->status_lock, flags);
  3320. wait_event(modem->wait_tx_done_q,
  3321. (TX_FIFO_SZ == atomic_read(&modem->tx_fifo_cnt)));
  3322. if (ch_id == CTRL_CH_ID)
  3323. pr_debug("[C2K] after wait tx done\n");
  3324. spin_lock_irqsave(&modem->status_lock, flags);
  3325. if (modem->status == MD_OFF) {
  3326. spin_unlock_irqrestore(&modem->status_lock, flags);
  3327. LOGPRT(LOG_NOTICE, "c2k off now, ignore\n");
  3328. goto terminate;
  3329. }
  3330. spin_unlock_irqrestore(&modem->status_lock, flags);
  3331. #endif
  3332. if (modem->cbp_data->flow_ctrl_enable) {
  3333. if (c2k_gpio_get_value
  3334. (modem->cbp_data->cbp_flow_ctrl->wait_gpio) !=
  3335. modem->cbp_data->gpio_flow_ctrl_polar) {
  3336. if (FLOW_CTRL_ENABLE ==
  3337. atomic_read(&modem->cbp_data->cbp_flow_ctrl->state))
  3338. atomic_set(&modem->cbp_data->
  3339. cbp_flow_ctrl->state,
  3340. FLOW_CTRL_DISABLE);
  3341. } else {
  3342. while (1) { /*print added for testing,to be removed */
  3343. if (modem->status == MD_OFF
  3344. ||
  3345. ((modem->status == MD_EXCEPTION
  3346. || modem->status == MD_EXCEPTION_ONGOING)
  3347. && (ch_id != EXCP_CTRL_CH_ID)
  3348. && (ch_id != EXCP_MSG_CH_ID))) {
  3349. LOGPRT(LOG_ERR,
  3350. "%s %d: card is removed when channel%d flow is enable,data is dropped\n",
  3351. __func__, __LINE__, ch_id);
  3352. sdio_tx_rx_printk(buf, 1);
  3353. goto terminate;
  3354. }
  3355. if (modem_fc_flag < MODEM_FC_PRINT_MAX)
  3356. LOGPRT(LOG_ERR,
  3357. "%s %d: channel%d flow ctrl before!\n",
  3358. __func__, __LINE__, ch_id);
  3359. atomic_set(&modem->cbp_data->
  3360. cbp_flow_ctrl->state,
  3361. FLOW_CTRL_ENABLE);
  3362. modem->cbp_data->
  3363. flow_ctrl_wait_event
  3364. (modem->cbp_data->cbp_flow_ctrl);
  3365. if (modem_fc_flag < MODEM_FC_PRINT_MAX) {
  3366. LOGPRT(LOG_ERR,
  3367. "%s %d: channel%d flow ctrl after!\n",
  3368. __func__, __LINE__, ch_id);
  3369. modem_fc_flag++;
  3370. }
  3371. if (c2k_gpio_get_value
  3372. (modem->cbp_data->
  3373. cbp_flow_ctrl->wait_gpio) !=
  3374. modem->cbp_data->gpio_flow_ctrl_polar) {
  3375. LOGPRT(LOG_ERR,
  3376. "%s %d: channel%d flow ctrl ok!\n",
  3377. __func__, __LINE__, ch_id);
  3378. atomic_set(&modem->
  3379. cbp_data->cbp_flow_ctrl->
  3380. state, FLOW_CTRL_DISABLE);
  3381. modem_fc_flag = 0;
  3382. break;
  3383. }
  3384. }
  3385. }
  3386. }
  3387. if ((modem->status == MD_EXCEPTION
  3388. || modem->status == MD_EXCEPTION_ONGOING)
  3389. && (ch_id != EXCP_CTRL_CH_ID) && (ch_id != EXCP_MSG_CH_ID)) {
  3390. LOGPRT(LOG_ERR,
  3391. "%s %d: modem exception now. channel%d data is dropped\n",
  3392. __func__, __LINE__, ch_id);
  3393. /* sdio_tx_rx_printk(buf, 1); */
  3394. goto terminate;
  3395. }
  3396. /*temp. if you want to disable 4-line, simply unmark the next line. */
  3397. /*modem->cbp_data->ipc_enable = 0; */
  3398. /*if 4-line enabled, do this to make sure md is awake */
  3399. if (modem->cbp_data->ipc_enable) {
  3400. asc_tx_ready_count(modem->cbp_data->tx_handle->name, 1);
  3401. tx_ready =
  3402. asc_tx_auto_ready(modem->cbp_data->tx_handle->name,
  3403. 1);
  3404. if (tx_ready != 0)
  3405. asc_tx_ready_count(modem->cbp_data->
  3406. tx_handle->name, 0);
  3407. }
  3408. if (modem->status == MD_OFF) {
  3409. LOGPRT(LOG_ERR,
  3410. "%s %d: card is removed when channel%d flow is enable,data is dropped\n",
  3411. __func__, __LINE__, ch_id);
  3412. /* sdio_tx_rx_printk(buf, 1); */
  3413. goto terminate;
  3414. }
  3415. if (func == modem->func && func && func->card) {
  3416. sdio_claim_host(func);
  3417. } else {
  3418. LOGPRT(LOG_ERR,
  3419. "%s %d: func changed during writing, terminate\n",
  3420. __func__, __LINE__);
  3421. goto terminate;
  3422. }
  3423. /*if hw just support one channel, cannot tx/rx at the same time, we should disable irq here */
  3424. if (modem->cbp_data->tx_disable_irq) {
  3425. ret = func_enable_irq(func, 0);
  3426. if (ret) {
  3427. LOGPRT(LOG_ERR,
  3428. "%s %d: channel%d func_disable_irq failed ret=%d\n",
  3429. __func__, __LINE__, ch_id, ret);
  3430. err_flag = 1;
  3431. goto release_host;
  3432. }
  3433. }
  3434. if (modem->cbp_data->data_ack_enable) {
  3435. atomic_set(&modem->cbp_data->cbp_data_ack->state,
  3436. MODEM_ST_TX_RX);
  3437. }
  3438. if ((ch_id == DATA_CH_ID) || (ch_id == SDIO_AT_CHANNEL_NUM)
  3439. || (ch_id == SDIO_AT2_CHANNEL_NUM)
  3440. || (ch_id == SDIO_AT3_CHANNEL_NUM)
  3441. || (ch_id == EXCP_CTRL_CH_ID) || (ch_id == EXCP_MSG_CH_ID)
  3442. || (ch_id == AGPS_CH_ID) || (ch_id == MD_LOG_CH_ID)) {
  3443. LOGPRT(LOG_NOTICE, "ch_id(%d)\n", ch_id);
  3444. sdio_tx_rx_printk(buf, 1);
  3445. }
  3446. #if PADDING_BY_BLOCK_SIZE
  3447. /*sdio_tx_rx_printk(buf, 1); */
  3448. block_cnt = len / DEFAULT_BLK_SIZE;
  3449. if (len % DEFAULT_BLK_SIZE)
  3450. padding_len = (block_cnt + 1) * DEFAULT_BLK_SIZE - len;
  3451. LOGPRT(LOG_INFO, "padding len %d\n", padding_len);
  3452. pad_begin_ptr = (char *)buf + len;
  3453. if (padding_len) {
  3454. memset(pad_begin_ptr, 0, padding_len);
  3455. len += padding_len;
  3456. msg_head->hw_head.len_hi = (len & 0xFF00) >> 8;
  3457. msg_head->hw_head.len_low = len & 0xFF;
  3458. LOGPRT(LOG_INFO, "change hw_head to %d %d\n",
  3459. msg_head->hw_head.len_low, msg_head->hw_head.len_hi);
  3460. }
  3461. #endif
  3462. #ifdef TX_DONE_TRACE
  3463. pr_debug("[C2K] dump before tx\n");
  3464. msdc_c2k_dump_int_register();
  3465. #endif
  3466. /*LOGPRT(LOG_DEBUG, "%s %d: write %d bytes to addr 0x%x\n", __func__, __LINE__, len, addr); */
  3467. if ((ch_id == CTRL_CH_ID) && len == 12) {
  3468. pr_debug("[C2K SDIO] write ctrl channel start, len = %zd\n",
  3469. len);
  3470. }
  3471. ret = sdio_writesb(func, addr, buf, len);
  3472. if (ret) {
  3473. LOGPRT(LOG_ERR, "%s %d: channel%d failed ret=%d\n", __func__,
  3474. __LINE__, ch_id, ret);
  3475. err_flag = 1;
  3476. goto release_host;
  3477. }
  3478. if (ch_id == CTRL_CH_ID)
  3479. pr_debug("[C2K SDIO] write ctrl channel done, len = %zd\n",
  3480. len);
  3481. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  3482. atomic_sub(len, &modem->tx_fifo_cnt);
  3483. #ifdef TX_DONE_TRACE
  3484. mod_timer(&timer_wait_tx_done, jiffies + msecs_to_jiffies(1000));
  3485. #endif
  3486. #if USE_CCIF_INTR
  3487. ccif_notify_c2k(TX_DATA_CH);
  3488. #endif
  3489. #endif
  3490. /*LOGPRT(LOG_ERR, "%s %d: channel%d data ack before!\n", __func__, __LINE__, index); */
  3491. if (modem->cbp_data->data_ack_enable) {
  3492. modem->cbp_data->data_ack_wait_event(modem->
  3493. cbp_data->cbp_data_ack);
  3494. }
  3495. /*LOGPRT(LOG_ERR, "%s %d: channel%d data ack after!\n", __func__, __LINE__, index); */
  3496. if (modem->cbp_data->tx_disable_irq) {
  3497. ret = func_enable_irq(func, 1);
  3498. if (ret) {
  3499. LOGPRT(LOG_ERR,
  3500. "%s %d: channel%d func_enable_irq failed ret=%d\n",
  3501. __func__, __LINE__, ch_id, ret);
  3502. err_flag = 1;
  3503. }
  3504. }
  3505. release_host:
  3506. sdio_release_host(func);
  3507. if (err_flag != 0) {
  3508. LOGPRT(LOG_ERR,
  3509. "%s %d: channel%d ret =%d signal err to user space\n",
  3510. __func__, __LINE__, ch_id, ret);
  3511. modem_err_indication_usr(1);
  3512. }
  3513. terminate:
  3514. if (tx_ready == 0)
  3515. asc_tx_ready_count(modem->cbp_data->tx_handle->name, 0);
  3516. }
  3517. static void modem_port_remove(struct sdio_modem *modem)
  3518. {
  3519. struct sdio_modem_port *port;
  3520. /*struct tty_struct *tty; */
  3521. /*unsigned long flags = 0; */
  3522. int index;
  3523. LOGPRT(LOG_NOTICE, "%s %d: Enter.\n", __func__, __LINE__);
  3524. for (index = 0; index < SDIO_TTY_NR; index++) {
  3525. port = modem->port[index];
  3526. atomic_set(&port->sflow_ctrl_state, SFLOW_CTRL_DISABLE);
  3527. wake_up(&port->sflow_ctrl_wait_q);
  3528. atomic_set(&modem->ctrl_port->sflow_ctrl_state,
  3529. SFLOW_CTRL_DISABLE);
  3530. wake_up(&modem->ctrl_port->sflow_ctrl_wait_q);
  3531. atomic_set(&modem->cbp_data->cbp_flow_ctrl->state,
  3532. FLOW_CTRL_DISABLE);
  3533. wake_up(&modem->cbp_data->cbp_flow_ctrl->wait_q);
  3534. atomic_set(&modem->cbp_data->cbp_data_ack->state,
  3535. MODEM_ST_READY);
  3536. wake_up(&modem->cbp_data->cbp_data_ack->wait_q);
  3537. if (port->write_q) {
  3538. LOGPRT(LOG_NOTICE,
  3539. "%s %d: port%d cancel_work_sync before.\n",
  3540. __func__, __LINE__, index);
  3541. cancel_work_sync(&port->write_work);
  3542. LOGPRT(LOG_NOTICE,
  3543. "%s %d: port%d cancel_work_sync after.\n",
  3544. __func__, __LINE__, index);
  3545. destroy_workqueue(port->write_q);
  3546. LOGPRT(LOG_NOTICE,
  3547. "%s %d: port%d destroy queue after.\n", __func__,
  3548. __LINE__, index);
  3549. }
  3550. LOGPRT(LOG_NOTICE, "%s %d: sdio_modem_table cleared.\n",
  3551. __func__, __LINE__);
  3552. #if !ENABLE_CHAR_DEV
  3553. mutex_lock(&port->port.mutex);
  3554. port->func = NULL;
  3555. tty = tty_port_tty_get(&port->port);
  3556. /*tty_hangup is async so is this safe as is ?? */
  3557. if (tty) {
  3558. LOGPRT(LOG_NOTICE,
  3559. "%s %d destroy tty,index=%d port->index=%d\n",
  3560. __func__, __LINE__, index, port->index);
  3561. tty_hangup(tty);
  3562. tty_kref_put(tty);
  3563. }
  3564. mutex_unlock(&port->port.mutex);
  3565. #endif
  3566. sdio_modem_tty_port_put(port);
  3567. }
  3568. LOGPRT(LOG_NOTICE, "%s %d: Leave.\n", __func__, __LINE__);
  3569. }
  3570. static void sdio_buffer_in_set_max_len(struct sdio_modem_port *port)
  3571. {
  3572. unsigned int index = port->index;
  3573. switch (index) {
  3574. case 0:
  3575. port->sdio_buf_in_max_num = SDIO_PPP_BUF_IN_MAX_NUM;
  3576. break;
  3577. case 1:
  3578. port->sdio_buf_in_max_num = SDIO_ETS_BUF_IN_MAX_NUM;
  3579. break;
  3580. case 2:
  3581. port->sdio_buf_in_max_num = SDIO_IFS_BUF_IN_MAX_NUM;
  3582. break;
  3583. case 3:
  3584. port->sdio_buf_in_max_num = SDIO_AT_BUF_IN_MAX_NUM;
  3585. break;
  3586. case 4:
  3587. port->sdio_buf_in_max_num = SDIO_PCV_BUF_IN_MAX_NUM;
  3588. break;
  3589. default:
  3590. port->sdio_buf_in_max_num = SDIO_DEF_BUF_IN_MAX_NUM;
  3591. break;
  3592. }
  3593. }
  3594. static int sdio_modem_port_init(struct sdio_modem_port *port, int index)
  3595. {
  3596. int ret = 0;
  3597. /*unsigned long flags = 0; */
  3598. kref_init(&port->kref);
  3599. spin_lock_init(&port->write_lock);
  3600. if (kfifo_alloc(&port->transmit_fifo, FIFO_SIZE, GFP_KERNEL)) {
  3601. LOGPRT(LOG_ERR, "%s %d : Couldn't allocate transmit_fifo\n",
  3602. __func__, __LINE__);
  3603. return -ENOMEM;
  3604. }
  3605. /*create port's write work queue */
  3606. port->name = "modem_sdio_write_wq";
  3607. sprintf(port->work_name, "%s%d", port->name, index);
  3608. port->write_q = create_singlethread_workqueue(port->work_name);
  3609. if (port->write_q == NULL) {
  3610. LOGPRT(LOG_ERR, "%s %d error creat write workqueue\n", __func__,
  3611. __LINE__);
  3612. return -ENOMEM;
  3613. }
  3614. port->index = index;
  3615. #if ENABLE_CCMNI
  3616. if (port->index != CCMNI_CH_ID - 1) {
  3617. INIT_WORK(&port->write_work, sdio_write_port_work);
  3618. } else {
  3619. INIT_WORK(&port->write_ccmni_work, sdio_write_ccmni_work);
  3620. INIT_WORK(&port->write_work, sdio_write_port_work);
  3621. }
  3622. port->tx_state = CCMNI_TX_READY;
  3623. spin_lock_init(&port->tx_state_lock);
  3624. #else
  3625. INIT_WORK(&port->write_work, sdio_write_port_work);
  3626. #endif
  3627. mutex_init(&port->sdio_buf_in_mutex);
  3628. INIT_LIST_HEAD(&port->sdio_buf_in_list);
  3629. port->sdio_buf_in = 0;
  3630. port->sdio_buf_in_num = 0;
  3631. port->sdio_buf_in_size = 0;
  3632. sdio_buffer_in_set_max_len(port);
  3633. port->tx_count = 0;
  3634. port->rx_count = 0;
  3635. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  3636. mutex_init(&port->sdio_assemble_mutex);
  3637. INIT_LIST_HEAD(&port->sdio_assemble_list);
  3638. #endif
  3639. init_waitqueue_head(&port->sflow_ctrl_wait_q);
  3640. atomic_set(&port->sflow_ctrl_state, SFLOW_CTRL_DISABLE);
  3641. sema_init(&port->write_sem, 1);
  3642. #if ENABLE_CHAR_DEV
  3643. init_waitqueue_head(&port->rx_wq);
  3644. #endif
  3645. return ret;
  3646. }
  3647. static ssize_t modem_log_level_show(struct kobject *kobj,
  3648. struct kobj_attribute *attr, char *buf)
  3649. {
  3650. char *s = buf;
  3651. s += sprintf(s, "%d\n", sdio_log_level);
  3652. return s - buf;
  3653. }
  3654. static ssize_t modem_log_level_store(struct kobject *kobj,
  3655. struct kobj_attribute *attr,
  3656. const char *buf, size_t n)
  3657. {
  3658. unsigned long val;
  3659. if (kstrtoul(buf, 10, &val))
  3660. return -EINVAL;
  3661. if (val < 0)
  3662. return -EINVAL;
  3663. sdio_log_level = val;
  3664. return n;
  3665. }
  3666. static ssize_t modem_refer_show(struct kobject *kobj,
  3667. struct kobj_attribute *attr, char *buf)
  3668. {
  3669. char *s = buf;
  3670. struct sdio_modem *modem = c2k_modem;
  3671. int i = 0;
  3672. if (!modem)
  3673. return -ENODEV;
  3674. for (i = 0; i < SDIO_TTY_NR; i++) {
  3675. s += sprintf(s, "TTY port%d Tx: times %d\n", i,
  3676. modem->port[i]->tx_count);
  3677. s += sprintf(s, "\n");
  3678. s += sprintf(s, "TTY port%d Rx: times %d\n", i,
  3679. modem->port[i]->rx_count);
  3680. }
  3681. return s - buf;
  3682. }
  3683. static ssize_t modem_refer_store(struct kobject *kobj,
  3684. struct kobj_attribute *attr, const char *buf,
  3685. size_t n)
  3686. {
  3687. return n;
  3688. }
  3689. static ssize_t modem_ctrl_on_show(struct kobject *kobj,
  3690. struct kobj_attribute *attr, char *buf)
  3691. {
  3692. struct sdio_modem_ctrl_port *ctrl_port = NULL;
  3693. struct sdio_modem *modem = c2k_modem;
  3694. /*struct sdio_modem_port *port; */
  3695. char *s = buf;
  3696. /*int ret=-1; */
  3697. LOGPRT(LOG_NOTICE, "%s: enter\n", __func__);
  3698. if (modem)
  3699. ctrl_port = modem->ctrl_port;
  3700. /*out:*/
  3701. s += sprintf(s, "ctrl state: %s\n",
  3702. ctrl_port->chan_state ? "enable" : "disable");
  3703. return s - buf;
  3704. }
  3705. static ssize_t modem_ctrl_on_store(struct kobject *kobj,
  3706. struct kobj_attribute *attr, const char *buf,
  3707. size_t n)
  3708. {
  3709. unsigned long val;
  3710. if (kstrtoul(buf, 10, &val))
  3711. return -EINVAL;
  3712. if (val < 0)
  3713. return -EINVAL;
  3714. if (val)
  3715. modem_on_off_ctrl_chan(1);
  3716. else
  3717. modem_on_off_ctrl_chan(0);
  3718. return n;
  3719. }
  3720. static ssize_t modem_dtr_send_show(struct kobject *kobj,
  3721. struct kobj_attribute *attr, char *buf)
  3722. {
  3723. /*char query_mode=1; */
  3724. int status = -1, ret = -1;
  3725. char *s = buf;
  3726. LOGPRT(LOG_NOTICE, "%s: enter\n", __func__);
  3727. status = modem_dcd_state();
  3728. if (ret < 0) {
  3729. LOGPRT(LOG_NOTICE,
  3730. "query cp ctrl channel state failed ret=%d\n", ret);
  3731. }
  3732. s += sprintf(s, "ctrl state: %d\n", status);
  3733. return s - buf;
  3734. }
  3735. static ssize_t modem_dtr_send_store(struct kobject *kobj,
  3736. struct kobj_attribute *attr,
  3737. const char *buf, size_t n)
  3738. {
  3739. unsigned long val;
  3740. if (kstrtoul(buf, 10, &val))
  3741. return -EINVAL;
  3742. if (val < 0)
  3743. return -EINVAL;
  3744. dtr_value = val;
  3745. modem_dtr_set(val, 1);
  3746. return n;
  3747. }
  3748. static ssize_t modem_dtr_query_show(struct kobject *kobj,
  3749. struct kobj_attribute *attr, char *buf)
  3750. {
  3751. /*char query_mode=1; */
  3752. int status = -1, ret = -1;
  3753. char *s = buf;
  3754. LOGPRT(LOG_NOTICE, "%s: enter\n", __func__);
  3755. status = modem_dcd_state();
  3756. if (status < 0) {
  3757. LOGPRT(LOG_NOTICE,
  3758. "query cp ctrl channel state failed ret=%d\n", ret);
  3759. s += sprintf(s, "ctrl state: %s\n", "N/A");
  3760. } else {
  3761. s += sprintf(s, "ctrl state: %d\n", status);
  3762. }
  3763. return s - buf;
  3764. }
  3765. static ssize_t modem_dtr_query_store(struct kobject *kobj,
  3766. struct kobj_attribute *attr,
  3767. const char *buf, size_t n)
  3768. {
  3769. unsigned long val;
  3770. /*int data; */
  3771. if (kstrtoul(buf, 10, &val))
  3772. return -EINVAL;
  3773. if (val < 0)
  3774. return -EINVAL;
  3775. modem_dcd_state();
  3776. return n;
  3777. }
  3778. static unsigned char loop_back_chan;
  3779. static ssize_t modem_loop_back_chan_show(struct kobject *kobj,
  3780. struct kobj_attribute *attr, char *buf)
  3781. {
  3782. return 0;
  3783. }
  3784. static ssize_t modem_loop_back_chan_store(struct kobject *kobj,
  3785. struct kobj_attribute *attr,
  3786. const char *buf, size_t n)
  3787. {
  3788. unsigned long val;
  3789. if (kstrtoul(buf, 10, &val))
  3790. return -EINVAL;
  3791. if (val < 0)
  3792. return -EINVAL;
  3793. if (val < 6) {
  3794. loop_back_chan = val;
  3795. } else {
  3796. LOGPRT(LOG_ERR, "%s %d error channel select, please < 6!\n",
  3797. __func__, __LINE__);
  3798. }
  3799. return n;
  3800. }
  3801. static ssize_t modem_loop_back_mod_show(struct kobject *kobj,
  3802. struct kobj_attribute *attr, char *buf)
  3803. {
  3804. return 0;
  3805. }
  3806. static ssize_t modem_loop_back_mod_store(struct kobject *kobj,
  3807. struct kobj_attribute *attr,
  3808. const char *buf, size_t n)
  3809. {
  3810. unsigned long val;
  3811. if (kstrtoul(buf, 10, &val))
  3812. return -EINVAL;
  3813. if (val < 0)
  3814. return -EINVAL;
  3815. if (val < 4) {
  3816. modem_loop_back_chan(loop_back_chan, val);
  3817. } else {
  3818. LOGPRT(LOG_ERR,
  3819. "%s %d error channel select, please check the option!\n",
  3820. __func__, __LINE__);
  3821. }
  3822. return n;
  3823. }
  3824. static ssize_t modem_ack_show(struct kobject *kobj, struct kobj_attribute *attr,
  3825. char *buf)
  3826. {
  3827. char *s = buf;
  3828. struct sdio_modem *modem = c2k_modem;
  3829. struct cbp_platform_data *cbp_pdata = NULL;
  3830. /*int ret =-1; */
  3831. if (modem)
  3832. cbp_pdata = modem->cbp_data;
  3833. if ((cbp_pdata != NULL) && (cbp_pdata->cbp_data_ack != NULL)) {
  3834. s += sprintf(s, "gpio[%d]\t state:[%d]\t polar[%d]\t ",
  3835. cbp_pdata->cbp_data_ack->wait_gpio,
  3836. atomic_read(&cbp_pdata->cbp_data_ack->state),
  3837. cbp_pdata->cbp_data_ack->wait_polar);
  3838. s += sprintf(s, "stored:[%d]\n",
  3839. c2k_gpio_get_value(modem->cbp_data->
  3840. cbp_flow_ctrl->wait_gpio));
  3841. }
  3842. /*out:*/
  3843. return s - buf;
  3844. }
  3845. static ssize_t modem_ack_store(struct kobject *kobj,
  3846. struct kobj_attribute *attr, const char *buf,
  3847. size_t n)
  3848. {
  3849. return n;
  3850. }
  3851. static ssize_t modem_flw_show(struct kobject *kobj, struct kobj_attribute *attr,
  3852. char *buf)
  3853. {
  3854. char *s = buf;
  3855. struct sdio_modem *modem = c2k_modem;
  3856. struct cbp_platform_data *cbp_pdata = NULL;
  3857. /*struct sdio_modem_port *port; */
  3858. /*int ret =-1; */
  3859. if (modem)
  3860. cbp_pdata = modem->cbp_data;
  3861. if ((cbp_pdata != NULL) && (cbp_pdata->cbp_flow_ctrl != NULL)) {
  3862. s += sprintf(s, "gpio[%d] \tstate:[%d]\t polar[%d]\t ",
  3863. cbp_pdata->cbp_flow_ctrl->wait_gpio,
  3864. atomic_read(&cbp_pdata->cbp_flow_ctrl->state),
  3865. cbp_pdata->cbp_flow_ctrl->wait_polar);
  3866. s += sprintf(s, "stored:[%d]\n",
  3867. c2k_gpio_get_value(modem->cbp_data->
  3868. cbp_flow_ctrl->wait_gpio));
  3869. }
  3870. /*out:*/
  3871. return s - buf;
  3872. }
  3873. static ssize_t modem_flw_store(struct kobject *kobj,
  3874. struct kobj_attribute *attr, const char *buf,
  3875. size_t n)
  3876. {
  3877. return n;
  3878. }
  3879. #define modem_attr(_name) \
  3880. static struct kobj_attribute _name##_attr = { \
  3881. .attr = { \
  3882. .name = __stringify(_name), \
  3883. .mode = 0660, \
  3884. }, \
  3885. .show = modem_##_name##_show, \
  3886. .store = modem_##_name##_store, \
  3887. }
  3888. modem_attr(log_level);
  3889. modem_attr(refer);
  3890. modem_attr(ctrl_on);
  3891. modem_attr(dtr_send);
  3892. modem_attr(dtr_query);
  3893. modem_attr(loop_back_chan);
  3894. modem_attr(loop_back_mod);
  3895. modem_attr(ack);
  3896. modem_attr(flw);
  3897. static struct attribute *modem_sdio_attr[] = {
  3898. &log_level_attr.attr,
  3899. &refer_attr.attr,
  3900. &ctrl_on_attr.attr,
  3901. &dtr_send_attr.attr,
  3902. &dtr_query_attr.attr,
  3903. &loop_back_chan_attr.attr,
  3904. &loop_back_mod_attr.attr,
  3905. &ack_attr.attr,
  3906. &flw_attr.attr,
  3907. NULL,
  3908. };
  3909. /*static struct kobject *modem_sdio_kobj;*/
  3910. static struct attribute_group g_modem_attr_group = {
  3911. .attrs = modem_sdio_attr,
  3912. };
  3913. int sdio_rawbulk_intercept(int port_num, unsigned int inception)
  3914. {
  3915. int ret = -ENODEV;
  3916. struct sdio_modem_port *port;
  3917. if (port_num >= RAWBULK_TID_AT) /*skip flashless port */
  3918. port_num++;
  3919. port = sdio_modem_tty_port_get(port_num);
  3920. if (!port || !port->func) {
  3921. LOGPRT(LOG_ERR, "%s %d failed\n", __func__, __LINE__);
  3922. return ret;
  3923. }
  3924. LOGPRT(LOG_DEBUG, "modem inception = %d\n", inception);
  3925. spin_lock(&port->inception_lock);
  3926. if ((!!inception) == port->inception) {
  3927. spin_unlock(&port->inception_lock);
  3928. return 0;
  3929. }
  3930. spin_unlock(&port->inception_lock);
  3931. spin_lock(&port->inception_lock);
  3932. if (inception != port->inception)
  3933. port->inception = !!inception;
  3934. spin_unlock(&port->inception_lock);
  3935. return 0;
  3936. }
  3937. int modem_buffer_push(int port_num, void *buf, int count)
  3938. {
  3939. int ret, data_len;
  3940. unsigned long flags;
  3941. struct sdio_modem *modem;
  3942. int chars_in_fifo = 0;
  3943. struct sdio_modem_port *port;
  3944. if (port_num >= RAWBULK_TID_AT) /*skip flashless port */
  3945. port_num++;
  3946. port = sdio_modem_tty_port_get(port_num);
  3947. ret = check_port(port);
  3948. if (ret < 0) {
  3949. LOGPRT(LOG_ERR, "%s %d invalid port\n", __func__, __LINE__);
  3950. return ret;
  3951. }
  3952. modem = port->modem;
  3953. if (count == 0)
  3954. return 0;
  3955. spin_lock_irqsave(&port->write_lock, flags);
  3956. data_len = FIFO_SIZE - kfifo_len(&port->transmit_fifo);
  3957. spin_unlock_irqrestore(&port->write_lock, flags);
  3958. if (data_len < count) {
  3959. LOGPRT(LOG_DEBUG, "%s %d: SDIO driver buffer is full!\n",
  3960. __func__, __LINE__);
  3961. return -ENOMEM;
  3962. }
  3963. spin_lock_irqsave(&modem->status_lock, flags);
  3964. if (modem->status != MD_OFF) {
  3965. spin_unlock_irqrestore(&modem->status_lock, flags);
  3966. chars_in_fifo = kfifo_len(&port->transmit_fifo);
  3967. if (count > (ONE_PACKET_MAX_SIZE - chars_in_fifo)) {
  3968. pr_debug("[C2K] port%d too many data pending...\n",
  3969. port->index);
  3970. return -ENOMEM;
  3971. }
  3972. ret =
  3973. kfifo_in_locked(&port->transmit_fifo, buf, count,
  3974. &port->write_lock);
  3975. queue_work(port->write_q, &port->write_work);
  3976. } else {
  3977. spin_unlock_irqrestore(&modem->status_lock, flags);
  3978. LOGPRT(LOG_NOTICE, "%s %d: port%d is removed!\n", __func__,
  3979. __LINE__, port->index);
  3980. }
  3981. return 0;
  3982. }
  3983. #ifdef CONFIG_EVDO_DT_VIA_SUPPORT
  3984. static int via_sdio_probe_func(struct sdio_modem *modem, struct sdio_func *func)
  3985. {
  3986. int ret = 0;
  3987. int index = 0;
  3988. struct sdio_modem_port *port = NULL;
  3989. unsigned long flags;
  3990. sdio_claim_host(func);
  3991. ret = sdio_enable_func(func);
  3992. if (ret) {
  3993. LOGPRT(LOG_ERR, "%s %d sdio enable func failed with ret = %d\n",
  3994. __func__, __LINE__, ret);
  3995. goto err_enable_func;
  3996. }
  3997. ret = sdio_set_block_size(func, 512);
  3998. if (ret) {
  3999. LOGPRT(LOG_ERR, "%s %d: set block size failed with ret = %d\n",
  4000. __func__, __LINE__, ret);
  4001. goto error_set_block_size;
  4002. }
  4003. sdio_writeb(func, 0x01, 0x28, &ret);
  4004. if (ret) {
  4005. LOGPRT(LOG_ERR,
  4006. "%s %d: sdio_writeb 0x28 failed with ret = %d\n",
  4007. __func__, __LINE__, ret);
  4008. goto error_set_block_size;
  4009. }
  4010. for (index = 0; index < SDIO_TTY_NR; index++) {
  4011. port = modem->port[index];
  4012. port->func = func;
  4013. /*LOGPRT(LOG_INFO, "%s %d %d port(0x%x), func(0x%x).\n",__func__,__LINE__, index, port, port->func); */
  4014. }
  4015. ret = sdio_claim_irq(func, modem_sdio_irq);
  4016. if (ret) {
  4017. LOGPRT(LOG_ERR, "%s %d sdio claim irq failed.\n", __func__,
  4018. __LINE__);
  4019. goto err_sdio_claim_irq;
  4020. }
  4021. spin_lock_irqsave(&modem->status_lock, flags);
  4022. /*when md exception, sdio will be remounted. but we should keep status not changed. */
  4023. if (modem->status != MD_EXCEPTION) {
  4024. modem->status = MD_READY;
  4025. LOGPRT(LOG_INFO, "%s %d: set md status ready.\n", __func__,
  4026. __LINE__);
  4027. }
  4028. spin_unlock_irqrestore(&modem->status_lock, flags);
  4029. LOGPRT(LOG_NOTICE, "%s %d: exit.\n", __func__, __LINE__);
  4030. sdio_release_host(func);
  4031. return ret;
  4032. err_sdio_claim_irq:
  4033. error_set_block_size:
  4034. sdio_disable_func(func);
  4035. err_enable_func:
  4036. sdio_release_host(func);
  4037. return ret;
  4038. }
  4039. #else
  4040. static int sdio_pio_func_wait_rdy(struct sdio_func *func)
  4041. {
  4042. unsigned int cnt = 500;
  4043. int raw_val;
  4044. int ret = 0;
  4045. while (cnt--) {
  4046. ret = sdio_func1_rd(func, &raw_val, SDIO_CCIR, sizeof(raw_val));
  4047. if (ret) {
  4048. LOGPRT(LOG_ERR, "%s %d: read SDIO_CCIR failed ret=%d\n",
  4049. __func__, __LINE__, ret);
  4050. msleep(100);
  4051. continue;
  4052. }
  4053. if (raw_val &
  4054. (SDIO_CCIR_F_FUNC_RDY | SDIO_CCIR_G_FUNC_RDY |
  4055. SDIO_CCIR_B_FUNC_RDY)) {
  4056. return 0;
  4057. }
  4058. msleep(100);
  4059. }
  4060. return -1;
  4061. }
  4062. /*should already claimed host when call this function*/
  4063. int sdio_pio_get_drv_own(struct sdio_func *func, struct sdio_modem *modem)
  4064. {
  4065. int ret;
  4066. int raw_val;
  4067. unsigned int cnt = 500;
  4068. if ((func == NULL) || (modem == NULL))
  4069. return -1;
  4070. /*already get the driver own */
  4071. if (modem->fw_own == 0)
  4072. return 0;
  4073. raw_val = SDIO_CHLPCR_FW_OWN_REQ_CLR;
  4074. ret = sdio_func1_wr(func, SDIO_CHLPCR, &raw_val, sizeof(raw_val));
  4075. if (ret) {
  4076. LOGPRT(LOG_ERR, "%s %d: write SDIO_CHLPCR failed ret=%d\n",
  4077. __func__, __LINE__, ret);
  4078. return -1;
  4079. }
  4080. /*check */
  4081. while (cnt--) {
  4082. ret =
  4083. sdio_func1_rd(func, &raw_val, SDIO_CHLPCR, sizeof(raw_val));
  4084. if (ret) {
  4085. LOGPRT(LOG_ERR,
  4086. "%s %d: read SDIO_CHLPCR failed ret=%d\n",
  4087. __func__, __LINE__, ret);
  4088. return -1;
  4089. }
  4090. if (modem->fw_own == 0)
  4091. return 0; /*set by interrupt handler */
  4092. if (raw_val & SDIO_CHLPCR_FW_OWN_REQ_SET) { /*Read will get the DRV own status */
  4093. modem->fw_own = 0;
  4094. break;
  4095. }
  4096. msleep(20);
  4097. }
  4098. return (modem->fw_own == 0) ? 0 : (-1);
  4099. }
  4100. /*should already claimed host when call this function*/
  4101. int sdio_pio_give_fw_own(struct sdio_func *func, struct sdio_modem *modem)
  4102. {
  4103. unsigned int raw_val;
  4104. int ret;
  4105. int cnt = 500;
  4106. int int_enable, err;
  4107. int_enable = sdio_f0_readb(func, 0x04, &err);
  4108. if (err)
  4109. LOGPRT(LOG_ERR, "%s %d read interrupt enable reg fail %d.\n",
  4110. __func__, __LINE__, err);
  4111. else {
  4112. LOGPRT(LOG_INFO,
  4113. "%s %d read interrupt enable reg success 0x%x.\n",
  4114. __func__, __LINE__, int_enable);
  4115. }
  4116. raw_val = SDIO_CHLPCR_FW_OWN_REQ_SET;
  4117. ret = sdio_func1_wr(func, SDIO_CHLPCR, &raw_val, sizeof(raw_val));
  4118. if (ret) {
  4119. LOGPRT(LOG_ERR, "%s %d: write SDIO_CHLPCR failed ret=%d\n",
  4120. __func__, __LINE__, ret);
  4121. return -1;
  4122. }
  4123. /*check */
  4124. while (cnt--) {
  4125. ret =
  4126. sdio_func1_rd(func, &raw_val, SDIO_CHLPCR, sizeof(raw_val));
  4127. if (ret) {
  4128. LOGPRT(LOG_ERR,
  4129. "%s %d: read SDIO_CHLPCR failed ret=%d\n",
  4130. __func__, __LINE__, ret);
  4131. return -1;
  4132. }
  4133. if ((raw_val & SDIO_CHLPCR_FW_OWN_REQ_SET) == 0) { /*Read will get the DRV own status */
  4134. modem->fw_own = 1;
  4135. break;
  4136. }
  4137. if (cnt % 10 == 0) {
  4138. LOGPRT(LOG_ERR, "%s %d: polling fw own retry (0x%x)\n",
  4139. __func__, __LINE__, raw_val);
  4140. #if 0
  4141. int_enable = sdio_f0_readb(func, 0x04, &err);
  4142. if (err)
  4143. LOGPRT(LOG_ERR,
  4144. "%s %d read interrupt enable reg fail %d.\n",
  4145. __func__, __LINE__, err);
  4146. else {
  4147. LOGPRT(LOG_INFO,
  4148. "%s %d read interrupt enable reg success 0x%x.\n",
  4149. __func__, __LINE__, int_enable);
  4150. }
  4151. #endif
  4152. }
  4153. msleep(20);
  4154. }
  4155. return (modem->fw_own == 1) ? 0 : (-1);
  4156. }
  4157. int sdio_pio_enable_com_interrupt(struct sdio_func *func)
  4158. {
  4159. unsigned int raw_val;
  4160. int ret = 0;
  4161. ret = sdio_func1_rd(func, &raw_val, SDIO_CHLPCR, sizeof(raw_val));
  4162. if (ret) {
  4163. LOGPRT(LOG_ERR, "%s %d: read SDIO_CHLPCR failed ret=%d\n",
  4164. __func__, __LINE__, ret);
  4165. return -1;
  4166. }
  4167. if (raw_val & SDIO_CHLPCR_INT_EN_SET) {
  4168. LOGPRT(LOG_ERR,
  4169. "%s %d: The interrupt of pio-based function have been enabled\n",
  4170. __func__, __LINE__);
  4171. return 0;
  4172. }
  4173. /*raw_val |= SDIO_CHLPCR_INT_EN_SET; */
  4174. raw_val = SDIO_CHLPCR_INT_EN_SET;
  4175. ret = sdio_func1_wr(func, SDIO_CHLPCR, &raw_val, sizeof(raw_val));
  4176. if (ret) {
  4177. LOGPRT(LOG_ERR,
  4178. "%s %d: Enable pio-based function's interrupt failed ret=%d\n",
  4179. __func__, __LINE__, ret);
  4180. return -1;
  4181. }
  4182. LOGPRT(LOG_INFO,
  4183. "%s %d: Enable pio-based function's com interrupt success (0x%x)\n",
  4184. __func__, __LINE__, raw_val);
  4185. ret = sdio_func1_rd(func, &raw_val, SDIO_CHLPCR, sizeof(raw_val));
  4186. if (ret) {
  4187. LOGPRT(LOG_ERR, "%s %d: read SDIO_CHLPCR failed ret=%d\n",
  4188. __func__, __LINE__, ret);
  4189. /*return -1; */
  4190. } else
  4191. LOGPRT(LOG_INFO, "%s %d: read SDIO_CHLPCR success 0x%x\n",
  4192. __func__, __LINE__, raw_val);
  4193. return 0;
  4194. }
  4195. int sdio_pio_disable_com_interrupt(struct sdio_func *func)
  4196. {
  4197. unsigned int raw_val;
  4198. int ret = 0;
  4199. ret = sdio_func1_rd(func, &raw_val, SDIO_CHLPCR, sizeof(raw_val));
  4200. if (ret) {
  4201. LOGPRT(LOG_ERR, "%s %d: read SDIO_CHLPCR failed ret=%d\n",
  4202. __func__, __LINE__, ret);
  4203. return -1;
  4204. }
  4205. if (!(raw_val & SDIO_CHLPCR_INT_EN_SET)) {
  4206. LOGPRT(LOG_ERR,
  4207. "%s %d: The interrupt of pio-based function have not been enabled\n",
  4208. __func__, __LINE__);
  4209. return 0;
  4210. }
  4211. /*raw_val |= SDIO_CHLPCR_INT_EN_CLR; */
  4212. raw_val = SDIO_CHLPCR_INT_EN_CLR;
  4213. ret = sdio_func1_wr(func, SDIO_CHLPCR, &raw_val, sizeof(raw_val));
  4214. if (ret) {
  4215. LOGPRT(LOG_ERR,
  4216. "%s %d: Disable pio-based function's interrupt failed ret=%d\n",
  4217. __func__, __LINE__, ret);
  4218. return -1;
  4219. }
  4220. LOGPRT(LOG_INFO,
  4221. "%s %d: Disable pio-based function's interrupt success (0x%x)\n",
  4222. __func__, __LINE__, raw_val);
  4223. ret = sdio_func1_rd(func, &raw_val, SDIO_CHLPCR, sizeof(raw_val));
  4224. if (ret) {
  4225. LOGPRT(LOG_ERR, "%s %d: read SDIO_CHLPCR failed ret=%d\n",
  4226. __func__, __LINE__, ret);
  4227. /*return -1; */
  4228. } else
  4229. LOGPRT(LOG_INFO, "%s %d: read SDIO_CHLPCR success 0x%x\n",
  4230. __func__, __LINE__, raw_val);
  4231. return 0;
  4232. }
  4233. int sdio_pio_set_int_clr_ctl(struct sdio_func *func, enum sdio_int_clr_ctl mod)
  4234. {
  4235. unsigned int raw_val = 0;
  4236. int ret;
  4237. ret = sdio_func1_rd(func, &raw_val, SDIO_CHCR, sizeof(raw_val));
  4238. if (ret) {
  4239. LOGPRT(LOG_ERR, "%s %d: read SDIO_CHCR failed ret=%d\n",
  4240. __func__, __LINE__, ret);
  4241. return -1;
  4242. }
  4243. if (mod == SDIO_INT_CTL_W1C) {
  4244. raw_val |= SDIO_CHCR_INT_CLR_CTRL;
  4245. ret = sdio_func1_wr(func, SDIO_CHCR, &raw_val, sizeof(raw_val));
  4246. if (ret) {
  4247. LOGPRT(LOG_ERR,
  4248. "%s %d: Set interrupt write 1 clear failed ret=%d\n",
  4249. __func__, __LINE__, ret);
  4250. return -1;
  4251. }
  4252. }
  4253. if (mod == SDIO_INT_CTL_RC) {
  4254. raw_val &= ~SDIO_CHCR_INT_CLR_CTRL;
  4255. ret = sdio_func1_wr(func, SDIO_CHCR, &raw_val, sizeof(raw_val));
  4256. if (ret) {
  4257. LOGPRT(LOG_ERR,
  4258. "%s %d: Set interrupt read clear failed ret=%d\n",
  4259. __func__, __LINE__, ret);
  4260. return -1;
  4261. }
  4262. }
  4263. return 0;
  4264. }
  4265. int sdio_pio_set_int_mask(struct sdio_func *func, int set_bits, int clr_bits)
  4266. {
  4267. struct sdio_modem *modem = sdio_get_drvdata(func);
  4268. int mask = 0;
  4269. int ret = 0;
  4270. int loop = 0;
  4271. mask |= set_bits;
  4272. mask &= ~clr_bits;
  4273. ret = sdio_func1_wr(func, SDIO_CHIER, &mask, sizeof(mask));
  4274. if (ret) {
  4275. LOGPRT(LOG_ERR, "%s %d: Set interrupt mask failed ret=%d\n",
  4276. __func__, __LINE__, ret);
  4277. return -1;
  4278. }
  4279. modem->int_mask.raw_val = mask;
  4280. LOGPRT(LOG_INFO, "%s %d: set interrupt mask success (0x%x)\n", __func__,
  4281. __LINE__, mask);
  4282. for (loop = 0; loop < 1; loop++) {
  4283. ret = sdio_func1_rd(func, &mask, SDIO_CHIER, sizeof(mask));
  4284. if (ret) {
  4285. LOGPRT(LOG_ERR,
  4286. "%s %d: read SDIO_CHIER failed ret=%d\n",
  4287. __func__, __LINE__, ret);
  4288. /*return -1; */
  4289. } else
  4290. LOGPRT(LOG_INFO,
  4291. "%s %d: read SDIO_CHIER success 0x%x\n",
  4292. __func__, __LINE__, mask);
  4293. /*msleep(100); */
  4294. }
  4295. return 0;
  4296. }
  4297. /*should already claimed host when call this function*/
  4298. int sdio_pio_enable_async_interrupt(struct sdio_func *func)
  4299. {
  4300. unsigned int raw_val;
  4301. int ret = 0;
  4302. ret = sdio_func1_rd(func, &raw_val, SDIO_CSDIOCSR, sizeof(raw_val));
  4303. if (ret) {
  4304. LOGPRT(LOG_ERR, "%s %d: read SDIO_CSDIOCSR failed ret=%d\n",
  4305. __func__, __LINE__, ret);
  4306. return -1;
  4307. }
  4308. if (raw_val & SDIO_CSDIOCSR_SDIO_INT_CTL) {
  4309. LOGPRT(LOG_INFO,
  4310. "%s %d: The async interrupt of pio-based function have been enabled\n",
  4311. __func__, __LINE__);
  4312. return 0;
  4313. }
  4314. raw_val |= SDIO_CSDIOCSR_SDIO_INT_CTL;
  4315. ret = sdio_func1_wr(func, SDIO_CSDIOCSR, &raw_val, sizeof(raw_val));
  4316. if (ret) {
  4317. LOGPRT(LOG_ERR,
  4318. "%s %d: Enable pio-based function's async interrupt failed ret=%d\n",
  4319. __func__, __LINE__, ret);
  4320. return -1;
  4321. }
  4322. LOGPRT(LOG_INFO,
  4323. "%s %d: Enable pio-based function's async interrupt success\n",
  4324. __func__, __LINE__);
  4325. return 0;
  4326. }
  4327. int sdio_pio_disable_async_interrupt(struct sdio_func *func)
  4328. {
  4329. unsigned int raw_val;
  4330. int ret = 0;
  4331. ret = sdio_func1_rd(func, &raw_val, SDIO_CSDIOCSR, sizeof(raw_val));
  4332. if (ret) {
  4333. LOGPRT(LOG_ERR, "%s %d: read SDIO_CSDIOCSR failed ret=%d\n",
  4334. __func__, __LINE__, ret);
  4335. return -1;
  4336. }
  4337. if (!(raw_val & SDIO_CSDIOCSR_SDIO_INT_CTL)) {
  4338. LOGPRT(LOG_INFO,
  4339. "%s %d: The async interrupt of pio-based function have been disabled\n",
  4340. __func__, __LINE__);
  4341. return 0;
  4342. }
  4343. raw_val &= ~SDIO_CSDIOCSR_SDIO_INT_CTL;
  4344. ret = sdio_func1_wr(func, SDIO_CSDIOCSR, &raw_val, sizeof(raw_val));
  4345. if (ret) {
  4346. LOGPRT(LOG_ERR,
  4347. "%s %d: Disable pio-based function's async interrupt failed ret=%d\n",
  4348. __func__, __LINE__, ret);
  4349. return -1;
  4350. }
  4351. LOGPRT(LOG_INFO,
  4352. "%s %d: Disable pio-based function's async interrupt success\n",
  4353. __func__, __LINE__);
  4354. return 0;
  4355. }
  4356. int check_img_header(struct sdio_modem *modem)
  4357. {
  4358. struct file *filp = NULL;
  4359. struct inode *inode = NULL;
  4360. loff_t fsize;
  4361. loff_t offset;
  4362. /*loff_t *pos; */
  4363. mm_segment_t old_fs;
  4364. int ret = 0;
  4365. struct md_check_header *header = NULL;
  4366. struct ccci_image_info *img;
  4367. char *img_str = c2k_img_info_str;
  4368. static int check_init;
  4369. if (check_init) {
  4370. LOGPRT(LOG_INFO, "%s: header already checked!\n", __func__);
  4371. LOGPRT(LOG_INFO, "%s\n", c2k_img_info_str);
  4372. return 0;
  4373. }
  4374. filp = filp_open(C2K_IMG_PATH, O_RDONLY, 0644);
  4375. if (IS_ERR(filp)) {
  4376. LOGPRT(LOG_ERR, "%s: open c2k md image fail!\n", __func__);
  4377. return -1;
  4378. }
  4379. if (!modem) {
  4380. LOGPRT(LOG_ERR, "%s: sdio_modem NULL, exit!\n", __func__);
  4381. goto close_out;
  4382. }
  4383. img = &modem->img_info;
  4384. inode = filp->f_dentry->d_inode;
  4385. fsize = inode->i_size;
  4386. LOGPRT(LOG_INFO, "%s: %s size %lld\n", __func__, C2K_IMG_PATH, fsize);
  4387. if (fsize < sizeof(struct md_check_header)) {
  4388. LOGPRT(LOG_ERR, "%s: %s size too small, go out!\n", __func__,
  4389. C2K_IMG_PATH);
  4390. goto close_out;
  4391. }
  4392. offset = 0 - sizeof(struct md_check_header);
  4393. old_fs = get_fs();
  4394. set_fs(KERNEL_DS);
  4395. header = kzalloc(sizeof(struct md_check_header), GFP_KERNEL);
  4396. if (!header) {
  4397. LOGPRT(LOG_ERR, "%s: alloc check header fail!\n", __func__);
  4398. goto close_out;
  4399. }
  4400. /*seek to the begin of check header */
  4401. filp->f_op->llseek(filp, offset, SEEK_END);
  4402. ret =
  4403. filp->f_op->read(filp, (char *)header,
  4404. sizeof(struct md_check_header), &filp->f_pos);
  4405. set_fs(old_fs);
  4406. if (ret > 0) {
  4407. ret = strncmp(header->check_header, MD_HEADER_MAGIC_NO, 12);
  4408. if (ret) {
  4409. LOGPRT(LOG_ERR, "md check header not exist!\n");
  4410. ret = 0;
  4411. } else {
  4412. img->ap_info.image_type = type_str[header->image_type];
  4413. img->ap_info.platform = get_ap_platform();
  4414. img->ap_info.mem_size = get_c2k_reserve_mem_size();
  4415. img->img_info.image_type = type_str[header->image_type];
  4416. img->img_info.platform = header->platform;
  4417. img->img_info.build_time = header->build_time;
  4418. img->img_info.build_ver = header->build_ver;
  4419. img->img_info.product_ver =
  4420. product_str[header->product_ver];
  4421. img->img_info.version = header->product_ver;
  4422. img->img_info.mem_size = header->mem_size;
  4423. /*LOGPRT(LOG_INFO, "%s: platform = %s, build_time = %s, build_ver = %s\n",
  4424. __func__, img_info->platform, img_info->build_time, img_info->build_ver); */
  4425. sprintf(img_str,
  4426. "MD:%s*%s*%s*%s*%s\nAP:%s*%s*%08x (MD)%08x\n",
  4427. img->img_info.image_type,
  4428. img->img_info.platform, img->img_info.build_ver,
  4429. img->img_info.build_time,
  4430. img->img_info.product_ver,
  4431. img->ap_info.image_type, img->ap_info.platform,
  4432. img->ap_info.mem_size, img->img_info.mem_size);
  4433. LOGPRT(LOG_INFO, "%s\n", img_str);
  4434. check_init = 1;
  4435. }
  4436. } else {
  4437. LOGPRT(LOG_ERR,
  4438. "%s: read c2k md img fail, cannot get check header!\n",
  4439. __func__);
  4440. }
  4441. close_out:
  4442. filp_close(filp, NULL);
  4443. return 0;
  4444. }
  4445. static int c2k_sdio_probe_func(struct sdio_modem *modem, struct sdio_func *func)
  4446. {
  4447. struct sdio_modem_port *port = NULL;
  4448. int ret = 0;
  4449. int index = 0;
  4450. unsigned long flags;
  4451. struct sdio_buf_in_packet *packet = NULL;
  4452. sdio_claim_host(func);
  4453. for (index = 0; index < SDIO_TTY_NR; index++) {
  4454. port = modem->port[index];
  4455. port->func = func;
  4456. atomic_set(&port->sflow_ctrl_state, SFLOW_CTRL_DISABLE);
  4457. }
  4458. modem->func = func;
  4459. ret = sdio_claim_irq(func, sdio_pio_intr_handler);
  4460. if (ret) {
  4461. LOGPRT(LOG_ERR, "%s %d sdio claim irq failed.\n", __func__,
  4462. __LINE__);
  4463. goto err_sdio_modem_port_init;
  4464. }
  4465. ret = sdio_enable_func(func);
  4466. if (ret) {
  4467. LOGPRT(LOG_ERR, "%s %d sdio enable func failed with ret = %d\n",
  4468. __func__, __LINE__, ret);
  4469. goto err_enable_func;
  4470. }
  4471. ret = sdio_pio_func_wait_rdy(func);
  4472. if (ret) {
  4473. LOGPRT(LOG_ERR, "%s %d: wait func ready failed with ret = %d\n",
  4474. __func__, __LINE__, ret);
  4475. goto disable_func;
  4476. }
  4477. LOGPRT(LOG_INFO, "%s %d: func ready\n", __func__, __LINE__);
  4478. ret = sdio_set_block_size(func, DEFAULT_BLK_SIZE);
  4479. if (ret) {
  4480. LOGPRT(LOG_ERR, "%s %d: set block size failed with ret = %d\n",
  4481. __func__, __LINE__, ret);
  4482. goto disable_func;
  4483. }
  4484. ret = sdio_pio_get_drv_own(func, modem);
  4485. if (ret) {
  4486. LOGPRT(LOG_ERR, "%s %d: get driver own failed with ret = %d\n",
  4487. __func__, __LINE__, ret);
  4488. goto disable_func;
  4489. }
  4490. ret = sdio_pio_disable_com_interrupt(func);
  4491. if (ret) {
  4492. LOGPRT(LOG_ERR,
  4493. "%s %d: disable interrupt output own failed with ret = %d\n",
  4494. __func__, __LINE__, ret);
  4495. goto give_own;
  4496. }
  4497. LOGPRT(LOG_INFO, "%s %d: sdio_pio_disable_com_interrupt done\n",
  4498. __func__, __LINE__);
  4499. ret = sdio_pio_set_int_clr_ctl(func, SDIO_INT_CTL_W1C);
  4500. if (ret) {
  4501. LOGPRT(LOG_ERR,
  4502. "%s %d: set int write 1 clear failed with ret = %d\n",
  4503. __func__, __LINE__, ret);
  4504. goto give_own;
  4505. }
  4506. modem->int_clr_ctl = SDIO_INT_CTL_W1C;
  4507. LOGPRT(LOG_INFO, "%s %d: sdio_pio_set_int_clr_ctl done\n", __func__,
  4508. __LINE__);
  4509. ret = sdio_pio_enable_async_interrupt(func);
  4510. if (ret) {
  4511. LOGPRT(LOG_ERR,
  4512. "%s %d: enable async interrupt failed with ret = %d\n",
  4513. __func__, __LINE__, ret);
  4514. goto give_own;
  4515. }
  4516. LOGPRT(LOG_INFO, "%s %d: sdio_pio_enable_async_interrupt done\n",
  4517. __func__, __LINE__);
  4518. ret = sdio_pio_set_int_mask(func, /*SDIO_CHIER_FW_OWN_BACK_EN| */
  4519. SDIO_CHIER_RX_RDY_EN |
  4520. SDIO_CHIER_TX_EMPTY_EN |
  4521. SDIO_CHIER_TX_UNDER_THOLD_EN |
  4522. SDIO_CHIER_TX_OVERFLOW_EN |
  4523. SDIO_CHIER_FW_INT_INDICATOR_EN |
  4524. SDIO_CHIER_FIRMWARE_INT_EN, 0);
  4525. if (ret) {
  4526. LOGPRT(LOG_ERR,
  4527. "%s %d: set interrupts' mask failed with ret = %d\n",
  4528. __func__, __LINE__, ret);
  4529. goto give_own;
  4530. }
  4531. LOGPRT(LOG_INFO, "%s %d: sdio_pio_set_int_mask done\n", __func__,
  4532. __LINE__);
  4533. spin_lock_irqsave(&modem->status_lock, flags);
  4534. /*when md exception, sdio will be remounted. but we should keep status not changed. */
  4535. if (modem->status != MD_EXCEPTION) {
  4536. del_timer(&modem->heart_beat_timer);
  4537. del_timer(&modem->poll_timer);
  4538. del_timer(&modem->force_assert_timer);
  4539. modem->status = MD_READY;
  4540. /*enable 4-line sync */
  4541. modem->cbp_data->ipc_enable = true;
  4542. LOGPRT(LOG_INFO, "%s %d: set md status ready.\n", __func__,
  4543. __LINE__);
  4544. spin_unlock_irqrestore(&modem->status_lock, flags);
  4545. cancel_work_sync(&modem->force_assert_work);
  4546. cancel_work_sync(&modem->poll_hb_work);
  4547. #if ENABLE_CHAR_DEV
  4548. port = modem->port[MD_LOG_CH_ID - 1];
  4549. mutex_lock(&port->sdio_buf_in_mutex);
  4550. /*clear pending data for mdlog channel */
  4551. while (!list_empty(&port->sdio_buf_in_list)) {
  4552. packet =
  4553. list_first_entry(&port->sdio_buf_in_list,
  4554. struct sdio_buf_in_packet, node);
  4555. list_del(&packet->node);
  4556. port->sdio_buf_in_num--;
  4557. port->sdio_buf_in_size -= packet->o_size;
  4558. kfree(packet->buffer);
  4559. kfree(packet);
  4560. }
  4561. mutex_unlock(&port->sdio_buf_in_mutex);
  4562. LOGPRT(LOG_INFO,
  4563. "%s: clear pending data for log channel done\n",
  4564. __func__);
  4565. #endif
  4566. } else {
  4567. spin_unlock_irqrestore(&modem->status_lock, flags);
  4568. }
  4569. LOGPRT(LOG_INFO, "%s %d: md status (%d).\n", __func__, __LINE__,
  4570. modem->status);
  4571. check_img_header(modem);
  4572. ret = sdio_pio_enable_com_interrupt(func);
  4573. if (ret) {
  4574. LOGPRT(LOG_ERR,
  4575. "%s %d: enable interrupt out failed with ret = %d\n",
  4576. __func__, __LINE__, ret);
  4577. goto give_own;
  4578. }
  4579. LOGPRT(LOG_INFO, "%s %d: sdio_pio_enable_com_interrupt done\n",
  4580. __func__, __LINE__);
  4581. LOGPRT(LOG_NOTICE, "%s %d: exit.\n", __func__, __LINE__);
  4582. sdio_release_host(func);
  4583. return ret;
  4584. sdio_release_irq(func);
  4585. err_sdio_modem_port_init:
  4586. modem_port_remove(modem);
  4587. for (index = 0; index < SDIO_TTY_NR; index++) {
  4588. port = modem->port[index];
  4589. kfree(port);
  4590. port = NULL;
  4591. }
  4592. give_own:
  4593. sdio_pio_give_fw_own(func, modem);
  4594. disable_func:
  4595. sdio_disable_func(func);
  4596. err_enable_func:
  4597. sdio_release_host(func);
  4598. return ret;
  4599. }
  4600. #endif
  4601. static int modem_sdio_probe(struct sdio_func *func,
  4602. const struct sdio_device_id *id)
  4603. {
  4604. struct sdio_modem *modem = NULL;
  4605. int ret = 0;
  4606. int index = 0;
  4607. /*unsigned long flags; */
  4608. LOGPRT(LOG_NOTICE, "%s %d: enter.\n", __func__, __LINE__);
  4609. LOGPRT(LOG_INFO, "modem_sdio_probe from %ps\n",
  4610. __builtin_return_address(0));
  4611. modem = c2k_modem;
  4612. modem->func = func;
  4613. sdio_set_drvdata(func, modem);
  4614. #ifdef CONFIG_EVDO_DT_VIA_SUPPORT
  4615. ret = via_sdio_probe_func(modem, func);
  4616. #else
  4617. c2k_sdio_install_eirq();
  4618. ret = c2k_sdio_probe_func(modem, func);
  4619. #endif
  4620. if (ret)
  4621. return ret;
  4622. for (index = 0; index < SDIO_TTY_NR; index++)
  4623. rawbulk_bind_sdio_channel(index);
  4624. SRC_trigger_signal(1);
  4625. /*VIA_trigger_signal(2); */
  4626. return ret;
  4627. }
  4628. void modem_reset_handler(void)
  4629. {
  4630. struct sdio_modem *modem = c2k_modem;
  4631. /*struct sdio_func *func = modem->func; */
  4632. struct sdio_func *func = NULL;
  4633. int ret = -1;
  4634. unsigned long flags;
  4635. LOGPRT(LOG_INFO, "%s %d: Enter.\n", __func__, __LINE__);
  4636. if (modem == NULL) {
  4637. LOGPRT(LOG_ERR, "%s %d: modem is NULL.\n", __func__, __LINE__);
  4638. goto out;
  4639. }
  4640. spin_lock_irqsave(&modem->status_lock, flags);
  4641. if (modem->status == MD_OFF) {
  4642. spin_unlock_irqrestore(&modem->status_lock, flags);
  4643. asc_tx_reset(modem->cbp_data->tx_handle->name); /*for IPO-H */
  4644. LOGPRT(LOG_ERR, "%s %d: md removed already.\n", __func__,
  4645. __LINE__);
  4646. goto out;
  4647. }
  4648. spin_unlock_irqrestore(&modem->status_lock, flags);
  4649. asc_tx_reset(modem->cbp_data->tx_handle->name);
  4650. func = modem->func;
  4651. spin_lock_irqsave(&modem->status_lock, flags);
  4652. /*when md exception, we will trigger this reset function. but we should keep status not changed. */
  4653. if (modem->status != MD_EXCEPTION) {
  4654. modem->status = MD_OFF;
  4655. LOGPRT(LOG_INFO, "%s %d: set md status off.\n", __func__,
  4656. __LINE__);
  4657. }
  4658. spin_unlock_irqrestore(&modem->status_lock, flags);
  4659. LOGPRT(LOG_NOTICE, "%s %d: cancel_work_sync(&dtr_work) before.\n",
  4660. __func__, __LINE__);
  4661. cancel_work_sync(&modem->dtr_work);
  4662. LOGPRT(LOG_NOTICE, "%s %d: cancel_work_sync(&dtr_work) after.\n",
  4663. __func__, __LINE__);
  4664. cancel_work_sync(&modem->dcd_query_work);
  4665. LOGPRT(LOG_NOTICE, "%s %d: cancel_work_sync(&dcd_query_work) after.\n",
  4666. __func__, __LINE__);
  4667. dcd_state = 0;
  4668. /*modem_port_remove(modem); */
  4669. sdio_claim_host(func);
  4670. ret = sdio_disable_func(func);
  4671. if (ret < 0)
  4672. LOGPRT(LOG_ERR, "%s: sdio_disable_func failed.\n", __func__);
  4673. ret = sdio_release_irq(func);
  4674. if (ret < 0)
  4675. LOGPRT(LOG_ERR, "%s: sdio_release_irq failed.\n", __func__);
  4676. sdio_release_host(func);
  4677. out:
  4678. LOGPRT(LOG_INFO, "%s %d: Leave.\n", __func__, __LINE__);
  4679. }
  4680. void modem_pre_stop(void)
  4681. {
  4682. struct sdio_modem *modem = c2k_modem;
  4683. /*struct sdio_func *func = modem->func; */
  4684. struct sdio_func *func = NULL;
  4685. int ret = 0;
  4686. func = modem->func;
  4687. if (!func || !func->card) {
  4688. LOGPRT(LOG_INFO, "%s %d: card removed, exit.\n", __func__, __LINE__);
  4689. return;
  4690. }
  4691. LOGPRT(LOG_INFO, "%s %d: Enter.\n", __func__, __LINE__);
  4692. sdio_claim_host(func);
  4693. ret = sdio_disable_func(func);
  4694. if (ret < 0)
  4695. LOGPRT(LOG_ERR, "%s: sdio_disable_func failed.\n", __func__);
  4696. ret = sdio_release_irq(func);
  4697. if (ret < 0)
  4698. LOGPRT(LOG_ERR, "%s: sdio_release_irq failed.\n", __func__);
  4699. sdio_release_host(func);
  4700. LOGPRT(LOG_INFO, "%s %d: Enter.\n", __func__, __LINE__);
  4701. }
  4702. static void modem_sdio_remove(struct sdio_func *func)
  4703. {
  4704. LOGPRT(LOG_NOTICE, "%s %d: Enter.\n", __func__, __LINE__);
  4705. LOGPRT(LOG_INFO, "modem_sdio_remove from %ps\n",
  4706. __builtin_return_address(0));
  4707. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  4708. c2k_sdio_uninstall_eirq();
  4709. #endif
  4710. LOGPRT(LOG_NOTICE, "%s %d: Leave.\n", __func__, __LINE__);
  4711. }
  4712. #ifdef CONFIG_EVDO_DT_VIA_SUPPORT
  4713. #define SDIO_VENDOR_ID_CBP 0x0296
  4714. #define SDIO_DEVICE_ID_CBP 0x5347
  4715. #else
  4716. #define SDIO_VENDOR_ID_CBP 0x037A /*0x0296 */
  4717. #define SDIO_DEVICE_ID_CBP 0xC200 /*0x5347 */
  4718. #endif
  4719. static const struct sdio_device_id modem_sdio_ids[] = {
  4720. {SDIO_DEVICE(SDIO_VENDOR_ID_CBP, SDIO_DEVICE_ID_CBP)}, /*VIA-Telecom CBP */
  4721. {} /*Terminating entry */
  4722. };
  4723. MODULE_DEVICE_TABLE(sdio, modem_sdio_ids);
  4724. static int c2k_sdio_suspend(struct device *dev)
  4725. {
  4726. struct sdio_func *func = dev_to_sdio_func(dev);
  4727. int ret;
  4728. if (func) {
  4729. LOGPRT(LOG_INFO, "c2k_sdio_suspend\n");
  4730. ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
  4731. }
  4732. return 0;
  4733. }
  4734. static int c2k_sdio_resume(struct device *dev)
  4735. {
  4736. return 0;
  4737. }
  4738. static const struct dev_pm_ops c2k_sdio_pm_ops = {
  4739. .suspend = c2k_sdio_suspend,
  4740. .resume = c2k_sdio_resume,
  4741. };
  4742. static struct sdio_driver modem_sdio_driver = {
  4743. .probe = modem_sdio_probe,
  4744. .remove = modem_sdio_remove,
  4745. .name = "modem_sdio",
  4746. .id_table = modem_sdio_ids,
  4747. .drv = {
  4748. .owner = THIS_MODULE,
  4749. .pm = &c2k_sdio_pm_ops,
  4750. }
  4751. };
  4752. #if ENABLE_CCMNI
  4753. int sdio_modem_ccmni_send_pkt(int md_id, int tx_ch, void *data)
  4754. {
  4755. struct sdio_modem *modem = NULL;
  4756. struct sdio_modem_port *ccmni_port = NULL;
  4757. struct sk_buff *skb = NULL;
  4758. struct sdio_msg_head *msg_head = NULL;
  4759. unsigned long flags;
  4760. int ret = 0;
  4761. unsigned int data_len;
  4762. unsigned int todo;
  4763. int chars_in_fifo = 0;
  4764. LOGPRT(LOG_DEBUG, "%s: enter...\n", __func__);
  4765. if (md_id != SDIO_MD_ID) {
  4766. LOGPRT(LOG_ERR,
  4767. "%s: sdio_modem_send_pkt failed: wrong md_id.\n",
  4768. __func__);
  4769. return CCMNI_ERR_TX_INVAL;
  4770. }
  4771. ccmni_port = sdio_modem_tty_port_get(CCMNI_CH_ID - 1);
  4772. modem = ccmni_port->modem;
  4773. if (!ccmni_port || modem->status == 0) {
  4774. LOGPRT(LOG_ERR,
  4775. "%s: sdio_modem_send_pkt failed: ccmni port is NULL.\n",
  4776. __func__);
  4777. goto md_not_ready_err_exit;
  4778. }
  4779. LOGPRT(LOG_DEBUG, "%s: get port done...\n", __func__);
  4780. skb = (struct sk_buff *)data;
  4781. todo = skb->len;
  4782. msg_head =
  4783. (struct sdio_msg_head *)skb_push(skb, sizeof(struct sdio_msg_head));
  4784. msg_head->start_flag = 0xFE;
  4785. msg_head->chanInfo =
  4786. (0x0F & (ccmni_port->index + 1)) + (0xF0 & (tx_ch << 4));
  4787. msg_head->tranHi = 0x0F & (todo >> 8);
  4788. msg_head->tranLow = 0xFF & todo;
  4789. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  4790. msg_head->hw_head.len_hi =
  4791. ((todo + sizeof(struct sdio_msg_head)) & 0xFF00) >> 8;
  4792. msg_head->hw_head.len_low =
  4793. (todo + sizeof(struct sdio_msg_head)) & 0xFF;
  4794. #endif
  4795. data_len = skb->len; /*as skb->len already included sdio_msg_head after skb_push */
  4796. data = (void *)(skb->data);
  4797. LOGPRT(LOG_DEBUG,
  4798. "%s %d msg_head(0x%x, 0x%x, 0x%x, 0x%x), data_len(%d), todo(%d)\n",
  4799. __func__, __LINE__, msg_head->start_flag, msg_head->chanInfo,
  4800. msg_head->tranHi, msg_head->tranLow, data_len, todo);
  4801. LOGPRT(LOG_DEBUG, "%s %d msg_head addr(%p) data addr(%p)\n", __func__,
  4802. __LINE__, (int *)msg_head, (int *)data);
  4803. if (ccmni_port->inception) {
  4804. skb_pull(skb, sizeof(struct sdio_msg_head));
  4805. LOGPRT(LOG_ERR, "%s %d check why come here\n", __func__,
  4806. __LINE__);
  4807. return CCMNI_ERR_TX_BUSY;
  4808. }
  4809. chars_in_fifo = kfifo_len(&ccmni_port->transmit_fifo);
  4810. if (data_len > (FIFO_SIZE - chars_in_fifo)) {
  4811. LOGPRT(LOG_DEBUG, "%s %d FIFO size is not enough!(%d)\n",
  4812. __func__, __LINE__, chars_in_fifo);
  4813. skb_pull(skb, sizeof(struct sdio_msg_head));
  4814. spin_lock_irqsave(&ccmni_port->tx_state_lock, flags);
  4815. /* stop tx queue */
  4816. LOGPRT(LOG_INFO, "ccmni port %d is stopped.\n",
  4817. ccmni_port->index);
  4818. ccmni_ops.md_state_callback(md_id, tx_ch, TX_FULL);
  4819. ccmni_port->tx_state = CCMNI_TX_STOP;
  4820. spin_unlock_irqrestore(&ccmni_port->tx_state_lock, flags);
  4821. return CCMNI_ERR_TX_BUSY;
  4822. }
  4823. spin_lock_irqsave(&modem->status_lock, flags);
  4824. if (modem->status != MD_OFF) {
  4825. spin_unlock_irqrestore(&modem->status_lock, flags);
  4826. ret =
  4827. kfifo_in_locked(&ccmni_port->transmit_fifo, data, data_len,
  4828. &ccmni_port->write_lock);
  4829. if (ret != data_len) {
  4830. LOGPRT(LOG_ERR,
  4831. "%s %d not all data pushed into fifo(%d/%d)!\n",
  4832. __func__, __LINE__, ret, data_len);
  4833. }
  4834. /*free skb if we return tx OK */
  4835. dev_kfree_skb_any(skb);
  4836. LOGPRT(LOG_DEBUG,
  4837. "%s %d push %d bytes to fifo!(0x%x, 0x%x, 0x%x, 0x%x)\n",
  4838. __func__, __LINE__, ret, *(char *)data,
  4839. *((char *)data + 1), *((char *)data + 2),
  4840. *((char *)data + 3));
  4841. queue_work(ccmni_port->write_q, &ccmni_port->write_ccmni_work);
  4842. } else {
  4843. spin_unlock_irqrestore(&modem->status_lock, flags);
  4844. LOGPRT(LOG_NOTICE, "%s %d: port%d is removed!\n", __func__,
  4845. __LINE__, ccmni_port->index);
  4846. goto md_not_ready_err_exit;
  4847. }
  4848. LOGPRT(LOG_DEBUG, "%s %d: port%d write done\n", __func__, __LINE__,
  4849. ccmni_port->index);
  4850. return data_len;
  4851. md_not_ready_err_exit:
  4852. return CCMNI_ERR_MD_NO_READY;
  4853. }
  4854. #endif
  4855. #if ENABLE_CHAR_DEV
  4856. static unsigned int char_dev_major;
  4857. static void *dev_class;
  4858. static int dev_char_open(struct inode *inode, struct file *file)
  4859. {
  4860. /*int major = imajor(inode); */
  4861. int minor = iminor(inode);
  4862. struct sdio_modem_port *port;
  4863. port = sdio_modem_tty_port_get(minor);
  4864. if (atomic_read(&port->usage_cnt))
  4865. return -EBUSY;
  4866. LOGPRT(LOG_INFO, "port %d open with flag %X by %s\n", port->index,
  4867. file->f_flags, current->comm);
  4868. kfifo_reset(&port->transmit_fifo);
  4869. LOGPRT(LOG_INFO, "port %d kfifo len %d\n", port->index,
  4870. kfifo_len(&port->transmit_fifo));
  4871. atomic_inc(&port->usage_cnt);
  4872. file->private_data = port;
  4873. nonseekable_open(inode, file);
  4874. return 0;
  4875. }
  4876. static int dev_char_close(struct inode *inode, struct file *file)
  4877. {
  4878. struct sdio_modem_port *port =
  4879. (struct sdio_modem_port *)file->private_data;
  4880. /*unsigned long flags; */
  4881. struct sdio_buf_in_packet *packet = NULL;
  4882. LOGPRT(LOG_INFO, "port %d close by %s\n", port->index, current->comm);
  4883. atomic_dec(&port->usage_cnt);
  4884. mutex_lock(&port->sdio_buf_in_mutex);
  4885. /*clear pending data */
  4886. while (!list_empty(&port->sdio_buf_in_list)) {
  4887. packet =
  4888. list_first_entry(&port->sdio_buf_in_list,
  4889. struct sdio_buf_in_packet, node);
  4890. list_del(&packet->node);
  4891. port->sdio_buf_in_num--;
  4892. port->sdio_buf_in_size -= packet->o_size;
  4893. kfree(packet->buffer);
  4894. kfree(packet);
  4895. }
  4896. mutex_unlock(&port->sdio_buf_in_mutex);
  4897. return 0;
  4898. }
  4899. static long dev_char_ioctl(struct file *file, unsigned int cmd,
  4900. unsigned long arg)
  4901. {
  4902. struct sdio_modem_port *port =
  4903. (struct sdio_modem_port *)file->private_data;
  4904. LOGPRT(LOG_INFO, "ioctl is not supported on port %d by %s, %x\n",
  4905. port->index, current->comm, cmd);
  4906. return 0;
  4907. }
  4908. #ifdef CONFIG_COMPAT
  4909. static long dev_char_compat_ioctl(struct file *filp, unsigned int cmd,
  4910. unsigned long arg)
  4911. {
  4912. return filp->f_op->unlocked_ioctl(filp, cmd,
  4913. (unsigned long)compat_ptr(arg));
  4914. }
  4915. #endif
  4916. static ssize_t dev_char_read(struct file *file, char *buf, size_t count,
  4917. loff_t *ppos)
  4918. {
  4919. struct sdio_buf_in_packet *packet = NULL;
  4920. int read_len = 0, read_curr = 0, full_pkt_done = 0, user_available =
  4921. count, ret = 0;
  4922. struct sdio_modem_port *port =
  4923. (struct sdio_modem_port *)file->private_data;
  4924. if (list_empty(&port->sdio_buf_in_list)) {
  4925. if (!(file->f_flags & O_NONBLOCK)) {
  4926. ret =
  4927. wait_event_interruptible(port->rx_wq,
  4928. !list_empty
  4929. (&port->sdio_buf_in_list));
  4930. if (ret == -ERESTARTSYS) {
  4931. ret = -EINTR;
  4932. goto exit;
  4933. }
  4934. } else {
  4935. ret = -EAGAIN;
  4936. goto exit;
  4937. }
  4938. }
  4939. /*LOGPRT(LOG_INFO, "reading on port%d count=%zu\n", port->index, count); */
  4940. get_one:
  4941. full_pkt_done = 0;
  4942. mutex_lock(&port->sdio_buf_in_mutex);
  4943. /*make sure list is not empty before dequeueing packet */
  4944. if (list_empty(&port->sdio_buf_in_list)) {
  4945. LOGPRT(LOG_ERR, "unexpected exit:port%d read_len=%d\n",
  4946. port->index, read_len);
  4947. mutex_unlock(&port->sdio_buf_in_mutex);
  4948. goto exit;
  4949. }
  4950. packet =
  4951. list_first_entry(&port->sdio_buf_in_list, struct sdio_buf_in_packet,
  4952. node);
  4953. if (user_available >= packet->size) {
  4954. full_pkt_done = 1;
  4955. read_curr = packet->size;
  4956. user_available -= packet->size;
  4957. } else {
  4958. read_curr = user_available;
  4959. user_available = 0;
  4960. }
  4961. if (!packet->buffer || (packet->offset + read_curr) > packet->o_size) {
  4962. LOGPRT(LOG_INFO,
  4963. "reading on port%d %p o_size=%d size=%d offset=%d read_curr=%d\n",
  4964. port->index, packet, packet->o_size, packet->size,
  4965. packet->offset, read_curr);
  4966. BUG_ON(1);
  4967. }
  4968. if (copy_to_user
  4969. (buf + read_len, packet->buffer + packet->offset, read_curr)) {
  4970. LOGPRT(LOG_ERR,
  4971. "reading on port%d %p copy_to_user fail: o_size=%d size=%d offset=%d read_curr=%d\n",
  4972. port->index, packet, packet->o_size, packet->size,
  4973. packet->offset, read_curr);
  4974. ret = -EFAULT;
  4975. mutex_unlock(&port->sdio_buf_in_mutex);
  4976. goto exit;
  4977. }
  4978. packet->size -= read_curr;
  4979. packet->offset += read_curr;
  4980. read_len += read_curr;
  4981. if (full_pkt_done) {
  4982. list_del(&packet->node);
  4983. port->sdio_buf_in_num--;
  4984. port->sdio_buf_in_size -= packet->o_size;
  4985. kfree(packet->buffer);
  4986. kfree(packet);
  4987. /*LOGPRT(LOG_INFO, "reading on port%d free %p\n", port->index, packet); */
  4988. if (!list_empty(&port->sdio_buf_in_list) && user_available) {
  4989. LOGPRT(LOG_DEBUG, "read on port%d more, %d/%d/%zu\n",
  4990. port->index, ret, read_len, count);
  4991. mutex_unlock(&port->sdio_buf_in_mutex);
  4992. goto get_one;
  4993. }
  4994. }
  4995. mutex_unlock(&port->sdio_buf_in_mutex);
  4996. exit:
  4997. if (port->index == EXCP_MSG_CH_ID - 1
  4998. || port->index == SDIO_AT_CHANNEL_NUM - 1
  4999. || port->index == SDIO_AT2_CHANNEL_NUM - 1
  5000. || port->index == EXCP_CTRL_CH_ID - 1
  5001. || port->index == AGPS_CH_ID - 1
  5002. || port->index == SDIO_AT3_CHANNEL_NUM - 1)
  5003. LOGPRT(LOG_INFO, "read on port%d done, %d/%d/%zu\n",
  5004. port->index, ret, read_len, count);
  5005. else
  5006. LOGPRT(LOG_DEBUG, "read on port%d done, %d/%d/%zu\n",
  5007. port->index, ret, read_len, count);
  5008. return ret ? ret : read_len;
  5009. }
  5010. static ssize_t dev_char_write(struct file *file, const char __user *buf,
  5011. size_t count, loff_t *ppos)
  5012. {
  5013. struct sdio_modem_port *port =
  5014. (struct sdio_modem_port *)file->private_data;
  5015. struct sdio_modem *modem = c2k_modem;
  5016. unsigned long flags, fflags;
  5017. int ret = 0;
  5018. unsigned int copied = 0;
  5019. int chars_in_fifo = 0;
  5020. ret = check_port(port);
  5021. if (ret < 0) {
  5022. LOGPRT(LOG_ERR, "%s %d check_port failed\n", __func__,
  5023. __LINE__);
  5024. return ret;
  5025. }
  5026. if ((port->index != (FLS_CH_ID - 1)) && c2k_modem_not_ready()) {
  5027. LOGPRT(LOG_ERR, "%s %d: modem is reset now.(%d)\n", __func__,
  5028. __LINE__, port->index);
  5029. return -ENODEV;
  5030. }
  5031. if ((port->index == (EXCP_CTRL_CH_ID - 1))
  5032. || (port->index == (EXCP_MSG_CH_ID - 1))) {
  5033. LOGPRT(LOG_INFO, "write on port%d\n", port->index);
  5034. }
  5035. if (port->inception)
  5036. return -EBUSY;
  5037. if (count > FIFO_SIZE) {
  5038. LOGPRT(LOG_ERR, "%s %d FIFO size is not enough!\n", __func__,
  5039. __LINE__);
  5040. return -1;
  5041. }
  5042. spin_lock_irqsave(&modem->status_lock, flags);
  5043. if (modem->status != MD_OFF) {
  5044. spin_unlock_irqrestore(&modem->status_lock, flags);
  5045. chars_in_fifo = kfifo_len(&port->transmit_fifo);
  5046. if ((port->index != (FLS_CH_ID - 1))
  5047. && (count > (ONE_PACKET_MAX_SIZE - chars_in_fifo))) {
  5048. pr_debug
  5049. ("[C2K]port%d too many(%d) data pending...flow ctrl(%d)\n",
  5050. port->index, chars_in_fifo,
  5051. atomic_read(&port->sflow_ctrl_state));
  5052. return -EBUSY;
  5053. }
  5054. /*ret = kfifo_in_locked(&port->transmit_fifo, buf, count, &port->write_lock); */
  5055. spin_lock_irqsave(&port->write_lock, fflags);
  5056. ret =
  5057. kfifo_from_user(&port->transmit_fifo, buf, count, &copied);
  5058. ret = ret == 0 ? copied : ret;
  5059. spin_unlock_irqrestore(&port->write_lock, fflags);
  5060. queue_work(port->write_q, &port->write_work);
  5061. } else {
  5062. spin_unlock_irqrestore(&modem->status_lock, flags);
  5063. LOGPRT(LOG_ERR, "%s %d: port%d is removed!\n", __func__,
  5064. __LINE__, port->index);
  5065. }
  5066. if ((port->index == (EXCP_CTRL_CH_ID - 1))
  5067. || (port->index == (EXCP_MSG_CH_ID - 1))) {
  5068. LOGPRT(LOG_INFO, "write on port%d for %d/%d/%zu\n", port->index,
  5069. ret, copied, count);
  5070. }
  5071. LOGPRT(LOG_DEBUG, "write on port%d for %d/%d/%zu\n", port->index, ret,
  5072. copied, count);
  5073. return ret;
  5074. }
  5075. static unsigned int dev_char_poll(struct file *fp,
  5076. struct poll_table_struct *poll)
  5077. {
  5078. struct sdio_modem_port *port =
  5079. (struct sdio_modem_port *)fp->private_data;
  5080. unsigned int mask = 0;
  5081. /*printk("[C2K] poll on %d\n", port->index); */
  5082. poll_wait(fp, &port->rx_wq, poll);
  5083. /*TODO: lack of poll wait for Tx */
  5084. if (!list_empty(&port->sdio_buf_in_list))
  5085. mask |= POLLIN | POLLRDNORM;
  5086. if (check_port(port) < 0)
  5087. mask |= POLLERR;
  5088. /*pr_debug("[C2K] poll done on %d, mask=%x\n", port->index, mask); */
  5089. return mask;
  5090. }
  5091. static const struct file_operations char_dev_fops = {
  5092. .owner = THIS_MODULE,
  5093. .open = &dev_char_open,
  5094. .read = &dev_char_read,
  5095. .write = &dev_char_write,
  5096. .release = &dev_char_close,
  5097. .unlocked_ioctl = &dev_char_ioctl,
  5098. #ifdef CONFIG_COMPAT
  5099. .compat_ioctl = &dev_char_compat_ioctl,
  5100. #endif
  5101. .poll = &dev_char_poll,
  5102. };
  5103. #endif
  5104. int modem_sdio_init(struct cbp_platform_data *pdata)
  5105. {
  5106. int ret;
  5107. #if ENABLE_CHAR_DEV
  5108. dev_t char_dev_num;
  5109. /*struct cdev *dev; */
  5110. #else
  5111. struct tty_driver *tty_drv;
  5112. #endif
  5113. struct sdio_modem *modem = NULL;
  5114. struct sdio_modem_port *port = NULL;
  5115. int index = 0;
  5116. unsigned long flags;
  5117. pr_debug("%s %d: Enter.\n", __func__, __LINE__);
  5118. #if ENABLE_CHAR_DEV
  5119. ret =
  5120. alloc_chrdev_region(&char_dev_num, 0, SDIO_TTY_NR, "c2k_ccci_node");
  5121. if (ret)
  5122. return -ENOMEM;
  5123. char_dev_major = MAJOR(char_dev_num);
  5124. dev_class = class_create(THIS_MODULE, "c2k_ccci_node");
  5125. #else
  5126. modem_sdio_tty_driver = tty_drv = alloc_tty_driver(SDIO_TTY_NR);
  5127. if (!tty_drv)
  5128. return -ENOMEM;
  5129. tty_drv->owner = THIS_MODULE;
  5130. tty_drv->driver_name = "modem_sdio";
  5131. tty_drv->name = "ttySDIO";
  5132. tty_drv->major = 0; /*dynamically allocated */
  5133. tty_drv->minor_start = 0;
  5134. tty_drv->type = TTY_DRIVER_TYPE_SERIAL;
  5135. tty_drv->subtype = SERIAL_TYPE_NORMAL;
  5136. tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
  5137. tty_drv->init_termios = tty_std_termios;
  5138. tty_drv->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
  5139. tty_drv->init_termios.c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD);
  5140. tty_drv->init_termios.c_cflag |= CREAD | CLOCAL | CS8;
  5141. tty_drv->init_termios.c_cflag &= ~(CRTSCTS);
  5142. tty_drv->init_termios.c_lflag &=
  5143. ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | ISIG);
  5144. tty_drv->init_termios.c_iflag &=
  5145. ~(INPCK | IGNPAR | PARMRK | ISTRIP | IXANY | ICRNL);
  5146. tty_drv->init_termios.c_iflag &= ~(IXON | IXOFF);
  5147. tty_drv->init_termios.c_oflag &= ~(OPOST | OCRNL);
  5148. tty_drv->init_termios.c_ispeed = 9600;
  5149. tty_drv->init_termios.c_ospeed = 9600;
  5150. tty_set_operations(tty_drv, &modem_tty_ops);
  5151. ret = tty_register_driver(tty_drv);
  5152. if (ret) {
  5153. LOGPRT(LOG_ERR, "%s: tty_register_driver failed.\n", __func__);
  5154. goto exit_reg_driver;
  5155. }
  5156. #endif
  5157. modem = kzalloc(sizeof(struct sdio_modem), GFP_KERNEL);
  5158. if (!modem) {
  5159. LOGPRT(LOG_ERR, "%s %d kzalloc sdio_modem failed.\n", __func__,
  5160. __LINE__);
  5161. ret = -ENOMEM;
  5162. goto err_kzalloc_sdio_modem;
  5163. }
  5164. modem->ctrl_port =
  5165. kzalloc(sizeof(struct sdio_modem_ctrl_port), GFP_KERNEL);
  5166. if (!modem->ctrl_port) {
  5167. LOGPRT(LOG_ERR, "%s %d kzalloc ctrl_port failed\n", __func__,
  5168. __LINE__);
  5169. ret = -ENOMEM;
  5170. goto err_kzalloc_ctrl_port;
  5171. }
  5172. modem->msg = kzalloc(sizeof(struct sdio_msg), GFP_KERNEL);
  5173. if (!modem->msg) {
  5174. LOGPRT(LOG_ERR, "%s %d kzalloc sdio_msg failed\n", __func__,
  5175. __LINE__);
  5176. ret = -ENOMEM;
  5177. goto err_kzalloc_sdio_msg;
  5178. }
  5179. modem->trans_buffer = kzalloc(TRANSMIT_BUFFER_SIZE, GFP_KERNEL);
  5180. if (!modem->trans_buffer) {
  5181. LOGPRT(LOG_ERR, "%s %d kzalloc trans_buffer failed\n", __func__,
  5182. __LINE__);
  5183. ret = -ENOMEM;
  5184. goto err_kzalloc_trans_buffer;
  5185. }
  5186. sema_init(&modem->sem, 1);
  5187. spin_lock_init(&modem->status_lock);
  5188. LOGPRT(LOG_INFO, "%s %d set md off!\n", __func__, __LINE__);
  5189. spin_lock_irqsave(&modem->status_lock, flags);
  5190. modem->status = MD_OFF;
  5191. spin_unlock_irqrestore(&modem->status_lock, flags);
  5192. modem->cbp_data = pdata;
  5193. pdata->modem = modem;
  5194. modem->ctrl_port->chan_state = CHAN_OFF;
  5195. init_waitqueue_head(&modem->ctrl_port->sflow_ctrl_wait_q);
  5196. atomic_set(&modem->ctrl_port->sflow_ctrl_state, SFLOW_CTRL_DISABLE);
  5197. INIT_WORK(&modem->dtr_work, modem_dtr_send);
  5198. INIT_WORK(&modem->dcd_query_work, modem_dcd_query);
  5199. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  5200. INIT_WORK(&modem->poll_hb_work, modem_heart_beat_poll_work);
  5201. INIT_WORK(&modem->force_assert_work, modem_force_assert_work);
  5202. INIT_WORK(&modem->smem_read_done_work, modem_smem_read_done_work);
  5203. #endif
  5204. #if ENABLE_CCMNI
  5205. ccmni_ops.init(SDIO_MD_ID, &sdio_ccmni_ops);
  5206. #endif
  5207. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  5208. modem->as_packet =
  5209. kzalloc(sizeof(struct sdio_assemble_packet), GFP_KERNEL);
  5210. if (!modem->as_packet) {
  5211. LOGPRT(LOG_ERR, "%s %d: kzalloc as_packet error\n", __func__,
  5212. __LINE__);
  5213. ret = -ENOMEM;
  5214. /*mutex_unlock(&port->sdio_assemble_mutex); */
  5215. goto err_kzalloc_trans_buffer; /*may need modify */
  5216. }
  5217. modem->as_packet->buffer = kzalloc(SDIO_ASSEMBLE_MAX, GFP_KERNEL);
  5218. if (!modem->as_packet->buffer) {
  5219. LOGPRT(LOG_ERR, "%s %d: kzalloc as_packet buffer error\n",
  5220. __func__, __LINE__);
  5221. ret = -ENOMEM;
  5222. kfree(modem->as_packet);
  5223. /*mutex_unlock(&port->sdio_assemble_mutex); */
  5224. goto err_kzalloc_trans_buffer; /*may need modify */
  5225. }
  5226. modem->as_packet->size = 0;
  5227. init_waitqueue_head(&modem->wait_tx_done_q);
  5228. modem->fw_own = 1;
  5229. atomic_set(&modem->as_packet->occupied, 0);
  5230. atomic_set(&modem->tx_fifo_cnt, TX_FIFO_SZ);
  5231. INIT_WORK(&modem->loopback_work, loopback_to_c2k);
  5232. #endif
  5233. for (index = 0; index < SDIO_TTY_NR; index++) {
  5234. port = kzalloc(sizeof(struct sdio_modem_port), GFP_KERNEL);
  5235. if (!port) {
  5236. LOGPRT(LOG_ERR,
  5237. "%s %d kzalloc sdio_modem_port %d failed.\n",
  5238. __func__, __LINE__, index);
  5239. ret = -ENOMEM;
  5240. goto err_kazlloc_sdio_modem_port;
  5241. }
  5242. /*printk("[MODEM SDIO] %s index[%d] 0x%x\n", __func__, index, port); */
  5243. #if !ENABLE_CHAR_DEV
  5244. tty_port_init(&port->port);
  5245. port->port.ops = &sdio_modem_port_ops;
  5246. #endif
  5247. port->modem = modem;
  5248. modem->port[index] = port;
  5249. spin_lock_init(&port->inception_lock);
  5250. port->inception = false;
  5251. }
  5252. for (index = 0; index < SDIO_TTY_NR; index++) {
  5253. port = modem->port[index];
  5254. ret = sdio_modem_port_init(port, index);
  5255. if (ret) {
  5256. LOGPRT(LOG_ERR, "%s %d sdio add port failed.\n",
  5257. __func__, __LINE__);
  5258. goto err_sdio_modem_port_init;
  5259. } else {
  5260. #if ENABLE_CHAR_DEV
  5261. struct device *dev;
  5262. cdev_init(&port->char_dev, &char_dev_fops);
  5263. port->char_dev.owner = THIS_MODULE;
  5264. ret =
  5265. cdev_add(&port->char_dev,
  5266. MKDEV(char_dev_major, port->index), 1);
  5267. dev =
  5268. device_create(dev_class, NULL,
  5269. MKDEV(char_dev_major, port->index),
  5270. NULL, "%s%d", "ttySDIO", port->index);
  5271. if (IS_ERR(dev)) {
  5272. ret = PTR_ERR(dev);
  5273. LOGPRT(LOG_ERR, "%s %d char create failed\n",
  5274. __func__, __LINE__);
  5275. goto err_sdio_modem_port_init;
  5276. }
  5277. #else
  5278. struct device *dev;
  5279. dev =
  5280. tty_port_register_device(&port->port,
  5281. modem_sdio_tty_driver,
  5282. port->index, NULL);
  5283. if (IS_ERR(dev)) {
  5284. ret = PTR_ERR(dev);
  5285. LOGPRT(LOG_ERR, "%s %d tty register failed\n",
  5286. __func__, __LINE__);
  5287. goto err_sdio_modem_port_init;
  5288. }
  5289. #endif
  5290. }
  5291. }
  5292. modem->c2k_kobj = c2k_kobject_add("modem_sdio");
  5293. if (!modem->c2k_kobj) {
  5294. ret = -ENOMEM;
  5295. goto err_create_kobj;
  5296. }
  5297. ret = sysfs_create_group(modem->c2k_kobj, &g_modem_attr_group);
  5298. c2k_modem = modem;
  5299. ret = sdio_register_driver(&modem_sdio_driver);
  5300. if (ret) {
  5301. LOGPRT(LOG_ERR, "%s: sdio_register_driver failed.\n", __func__);
  5302. goto exit_tty;
  5303. }
  5304. #ifdef TX_DONE_TRACE
  5305. setup_timer(&timer_wait_tx_done, wait_tx_done_timer,
  5306. (unsigned long)"C2K_TX");
  5307. #endif
  5308. #ifndef CONFIG_EVDO_DT_VIA_SUPPORT
  5309. setup_timer(&modem->heart_beat_timer, c2k_heart_beat_timer,
  5310. (unsigned long)modem);
  5311. setup_timer(&modem->poll_timer, c2k_poll_status_timer,
  5312. (unsigned long)modem);
  5313. setup_timer(&modem->force_assert_timer, c2k_force_assert_timer,
  5314. (unsigned long)modem);
  5315. #endif
  5316. LOGPRT(LOG_INFO, " %s: sdio driver is initialized!\n", __func__);
  5317. pr_debug("%s %d: Exit.\n", __func__, __LINE__);
  5318. return ret;
  5319. err_create_kobj:
  5320. err_sdio_modem_port_init:
  5321. modem_port_remove(modem);
  5322. err_kazlloc_sdio_modem_port:
  5323. for (index = 0; index < SDIO_TTY_NR; index++) {
  5324. port = modem->port[index];
  5325. kfree(port);
  5326. }
  5327. err_kzalloc_trans_buffer:
  5328. kfree(modem->msg);
  5329. err_kzalloc_sdio_msg:
  5330. kfree(modem->ctrl_port);
  5331. err_kzalloc_ctrl_port:
  5332. kfree(modem);
  5333. err_kzalloc_sdio_modem:
  5334. return ret;
  5335. exit_tty:
  5336. #if !ENABLE_CHAR_DEV
  5337. tty_unregister_driver(tty_drv);
  5338. #endif
  5339. /*exit_reg_driver:*/
  5340. LOGPRT(LOG_ERR, "%s: returning with error %d\n", __func__, ret);
  5341. #if !ENABLE_CHAR_DEV
  5342. put_tty_driver(tty_drv);
  5343. #endif
  5344. return ret;
  5345. }
  5346. void modem_sdio_exit(void)
  5347. {
  5348. sdio_unregister_driver(&modem_sdio_driver);
  5349. tty_unregister_driver(modem_sdio_tty_driver);
  5350. put_tty_driver(modem_sdio_tty_driver);
  5351. }