aboutsummaryrefslogtreecommitdiffstats
BranchCommit messageAuthorAge
archive/unc-master-3.0P-FP: fix BUG_ON releated to priority inheritanceBjoern Brandenburg13 years
archived-2013.1uncachedev: mmap memory that is not cached by CPUsGlenn Elliott12 years
archived-private-masterMerge branch 'wip-2.6.34' into old-private-masterAndrea Bastoni15 years
archived-semi-partMerge branch 'wip-semi-part' of ssh://cvs/cvs/proj/litmus/repo/litmus2010 int...Andrea Bastoni15 years
demoFurther refinementsJonathan Herman14 years
ecrts-pgm-finalMerge branch 'wip-ecrts14-pgm' of ssh://rtsrv.cs.unc.edu/home/litmus/litmus-r...Glenn Elliott12 years
ecrts14-pgm-finalMerge branch 'wip-ecrts14-pgm' of ssh://rtsrv.cs.unc.edu/home/litmus/litmus-r...Glenn Elliott12 years
gpusync-rtss12Final GPUSync implementation.Glenn Elliott12 years
gpusync/stagingRename IKGLP R2DGLP.Glenn Elliott12 years
linux-tipMerge branch 'slab/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/p...Linus Torvalds15 years
litmus2008-patch-seriesadd i386 feather-trace implementationBjoern B. Brandenburg16 years
masterPSN-EDF: use inferred_sporadic_job_release_atBjoern Brandenburg9 years
pgmmake it compileGlenn Elliott12 years
prop/litmus-signalsInfrastructure for Litmus signals.Glenn Elliott13 years
prop/robust-tie-breakFixed bug in edf_higher_prio().Glenn Elliott13 years
stagingFix tracepoint compilation errorFelipe Cerqueira13 years
test9/23/2016Namhoon Kim9 years
tracing-develTest kernel tracing events capabilitiesAndrea Bastoni16 years
v2.6.34-with-arm-patchessmsc911x: Add spinlocks around registers accessCatalin Marinas15 years
v2015.1Add ARM syscall def for get_current_budgetBjoern Brandenburg10 years
wip-2011.2-bbbLitmus core: simplify np-section protocolBjoern B. Brandenburg14 years
wip-2011.2-bbb-traceRefactor sched_trace_log_message() -> debug_trace_log_message()Andrea Bastoni14 years
wip-2012.3-gpuSOBLIV draining support for C-EDF.Glenn Elliott12 years
wip-2012.3-gpu-preportpick up last C-RM fileGlenn Elliott12 years
wip-2012.3-gpu-rtss13Fix critical bug in GPU tracker.Glenn Elliott12 years
wip-2012.3-gpu-sobliv-budget-w-ksharkProper sobliv draining and many bug fixes.Glenn Elliott12 years
wip-aedzl-finalMake it easier to compile AEDZL interfaces in liblitmus.Glenn Elliott15 years
wip-aedzl-revisedAdd sched_trace data for Apative EDZLGlenn Elliott15 years
wip-arbit-deadlineFix compilation bug.Glenn Elliott13 years
wip-aux-tasksDescription of refined aux task inheritance.Glenn Elliott13 years
wip-bbbGSN-EDF & Core: improve debug TRACE'ing for NP sectionsBjoern B. Brandenburg14 years
wip-bbb-prio-donuse correct timestampBjoern B. Brandenburg14 years
wip-better-breakImplement hash-based EDF tie-breaking.Glenn Elliott13 years
wip-binary-heapMake C-EDF work with simplified binheap_deleteGlenn Elliott13 years
wip-budgetAdded support for choices in budget policy enforcement.Glenn Elliott15 years
wip-colorSummarize schedulability with final recordJonathan Herman13 years
wip-color-jlhsched_color: Fixed two bugs causing crashing on experiment restart and a rare...Jonathan Herman13 years
wip-d10-hz1000Enable HZ=1000 on District 10Bjoern B. Brandenburg15 years
wip-default-clusteringFeature: Make default C-EDF clustering compile-time configurable.Glenn Elliott15 years
wip-dissipation-jericksoUpdate from 2.6.36 to 2.6.36.4Jeremy Erickson11 years
wip-dissipation2-jericksoUpdate 2.6.36 to 2.6.36.4Jeremy Erickson11 years
wip-ecrts14-pgmMerge branch 'wip-ecrts14-pgm' of ssh://rtsrv.cs.unc.edu/home/litmus/litmus-r...Glenn Elliott12 years
wip-edf-hsblast tested versionJonathan Herman14 years
wip-edf-osLookup table EDF-osJeremy Erickson12 years
wip-edf-tie-breakMerge branch 'wip-edf-tie-break' of ssh://rtsrv.cs.unc.edu/home/litmus/litmus...Glenn Elliott13 years
wip-edzl-critiqueUse hr_timer's active checks instead of having own flag.Glenn Elliott15 years
wip-edzl-finalImplementation of the EDZL scheduler.Glenn Elliott15 years
wip-edzl-revisedClean up comments.Glenn Elliott15 years
wip-eventsAdded support for tracing arbitrary actions.Jonathan Herman15 years
wip-extra-debugDBG: add additional tracingBjoern B. Brandenburg15 years
wip-fix-switch-jericksoAttempt to fix race condition with plugin switchingJeremy Erickson15 years
wip-fix3sched: show length of runqueue clock deactivation in /proc/sched_debugBjoern B. Brandenburg15 years
wip-fmlp-dequeueImprove FMLP queue management.Glenn Elliott14 years
wip-ft-irq-flagFeather-Trace: keep track of interrupt-related interference.Bjoern B. Brandenburg14 years
wip-gpu-cleanupEnable sched_trace log injection from userspaceGlenn Elliott13 years
wip-gpu-interruptsRemove option for threading of all softirqs.Glenn Elliott14 years
wip-gpu-rtas12Generalized GPU cost predictors + EWMA. (untested)Glenn Elliott13 years
wip-gpu-rtss12Final GPUSync implementation.Glenn Elliott13 years
wip-gpu-rtss12-srpexperimental changes to support GPUs under SRPGlenn Elliott13 years
wip-gpusync-mergeCleanup priority tracking for budget enforcement.Glenn Elliott11 years
wip-ikglpMove RSM and IKGLP imp. to own .c filesGlenn Elliott13 years
wip-k-fmlpMerge branch 'mpi-master' into wip-k-fmlpGlenn Elliott14 years
wip-kernel-coloringAdded recolor syscallNamhoon Kim7 years
wip-kernthreadsKludge work-queue processing into klitirqd.Glenn Elliott15 years
wip-klmirqd-to-auxAllow klmirqd threads to be given names.Glenn Elliott13 years
wip-ksharkMerge branch 'mpi-staging' into wip-ksharkJonathan Herman13 years
wip-litmus-3.2Merge commit 'v3.2' into litmus-stagingAndrea Bastoni13 years
wip-litmus2011.2Cleanup: Coding conformance for affinity stuff.Glenn Elliott14 years
wip-litmus3.0-2011.2Feather-Trace: keep track of interrupt-related interference.Bjoern B. Brandenburg14 years
wip-master-2.6.33-rtAvoid deadlock when switching task policy to BACKGROUND (ugly)Andrea Bastoni15 years
wip-mcRemoved ARM-specific hacks which disabled less common mixed-criticality featu...Jonathan Herman12 years
wip-mc-bipasaMC-EDF addedbipasa chattopadhyay13 years
wip-mc-jericksoSplit C/D queuesJeremy Erickson15 years
wip-mc2-cache-slackManually patched mc^2 related codeMing Yang10 years
wip-mcrit-maccosmeticMac Mollison15 years
wip-merge-3.0Prevent Linux to send IPI and queue tasks on remote CPUs.Andrea Bastoni14 years
wip-merge-v3.0Prevent Linux to send IPI and queue tasks on remote CPUs.Andrea Bastoni14 years
wip-migration-affinityNULL affinity dereference in C-EDF.Glenn Elliott14 years
wip-mmap-uncacheshare branch with othersGlenn Elliott13 years
wip-modechangeRTSS 2017 submissionNamhoon Kim8 years
wip-nested-lockingAppears to be working.Bryan Ward12 years
wip-omlp-gedfFirst implementation of G-OMLP.Glenn Elliott15 years
wip-paiSome cleanup of PAIGlenn Elliott14 years
wip-percore-lib9/21/2016Namhoon Kim9 years
wip-performanceCONFIG_DONT_PREEMPT_ON_TIE: Don't preeempt a scheduled task on priority tie.Glenn Elliott14 years
wip-pgmAdd PGM support to C-FLGlenn Elliott12 years
wip-pgm-splitFirst draft of C-FL-splitNamhoon Kim12 years
wip-pm-ovdAdd preemption-and-migration overhead tracing supportAndrea Bastoni15 years
wip-prio-inhP-EDF updated to use the generic pi framework.Glenn Elliott15 years
wip-prioq-dglBUG FIX: Support DGLs with PRIOQ_MUTEXGlenn Elliott13 years
wip-refactored-gedfGeneralizd architecture for GEDF-style scheduelrs to reduce code redundancy.Glenn Elliott15 years
wip-release-master-fixbugfix: release master CPU must signal task was pickedBjoern B. Brandenburg14 years
wip-robust-tie-breakEDF priority tie-breaks.Glenn Elliott13 years
wip-rt-ksharkMove task time accounting into the complete_job method.Jonathan Herman13 years
wip-rtas12-pgmScheduling of PGM jobs.Glenn Elliott13 years
wip-semi-partFix compile error with newer GCCJeremy Erickson12 years
wip-semi-part-edfos-jericksoUse initial CPU set by clientJeremy Erickson12 years
wip-shared-libTODO: Fix condition checks in replicate_page_move_mapping()Namhoon Kim9 years
wip-shared-lib2RTAS 2017 Submission ver.Namhoon Kim9 years
wip-shared-memInitial commit for shared libraryNamhoon Kim9 years
wip-splitting-jericksoFix release behaviorJeremy Erickson13 years
wip-splitting-omlp-jericksoBjoern's Dissertation Code with Priority DonationJeremy Erickson13 years
wip-stage-binheapAn efficient binary heap implementation.Glenn Elliott13 years
wip-sun-portDynamic memory allocation and clean exit for FeatherTraceChristopher Kenna15 years
wip-timer-tracebugfix: C-EDF, clear scheduled field of the correct CPU upon task_exitAndrea Bastoni15 years
wip-tracepointsAdd kernel-style events for sched_trace_XXX() functionsAndrea Bastoni14 years
 
TagDownloadAuthorAge
2015.1commit 8e51b37822...Bjoern Brandenburg10 years
2013.1commit bcaacec1ca...Glenn Elliott12 years
2012.3commit c158b5fbe4...Jonathan Herman13 years
2012.2commit b53c479a0f...Glenn Elliott13 years
2012.1commit 83b11ea1c6...Bjoern B. Brandenburg14 years
rtas12-mc-beta-expcommit 8e236ee20f...Christopher Kenna14 years
2011.1commit d11808b5c6...Christopher Kenna15 years
v2.6.37-rc4commit e8a7e48bb2...Linus Torvalds15 years
v2.6.37-rc3commit 3561d43fd2...Linus Torvalds15 years
v2.6.37-rc2commit e53beacd23...Linus Torvalds15 years
v2.6.37-rc1commit c8ddb2713c...Linus Torvalds15 years
v2.6.36commit f6f94e2ab1...Linus Torvalds15 years
2010.2commit 5c5456402d...Bjoern B. Brandenburg15 years
v2.6.36-rc8commit cd07202cc8...Linus Torvalds15 years
v2.6.36-rc7commit cb655d0f3d...Linus Torvalds15 years
v2.6.36-rc6commit 899611ee7d...Linus Torvalds15 years
v2.6.36-rc5commit b30a3f6257...Linus Torvalds15 years
v2.6.36-rc4commit 49553c2ef8...Linus Torvalds15 years
v2.6.36-rc3commit 2bfc96a127...Linus Torvalds15 years
v2.6.36-rc2commit 76be97c1fc...Linus Torvalds15 years
v2.6.36-rc1commit da5cabf80e...Linus Torvalds15 years
v2.6.35commit 9fe6206f40...Linus Torvalds15 years
v2.6.35-rc6commit b37fa16e78...Linus Torvalds15 years
v2.6.35-rc5commit 1c5474a65b...Linus Torvalds15 years
v2.6.35-rc4commit 815c4163b6...Linus Torvalds15 years
v2.6.35-rc3commit 7e27d6e778...Linus Torvalds15 years
v2.6.35-rc2commit e44a21b726...Linus Torvalds15 years
v2.6.35-rc1commit 67a3e12b05...Linus Torvalds15 years
2010.1commit 7c1ff4c544...Andrea Bastoni15 years
v2.6.34commit e40152ee1e...Linus Torvalds15 years
v2.6.33.4commit 4640b4e7d9...Greg Kroah-Hartman15 years
v2.6.34-rc7commit b57f95a382...Linus Torvalds15 years
v2.6.34-rc6commit 66f41d4c5c...Linus Torvalds15 years
v2.6.33.3commit 3e7ad8ed97...Greg Kroah-Hartman15 years
v2.6.34-rc5commit 01bf0b6457...Linus Torvalds15 years
v2.6.34-rc4commit 0d0fb0f9c5...Linus Torvalds15 years
v2.6.33.2commit 19f00f070c...Greg Kroah-Hartman15 years
v2.6.34-rc3commit 2eaa9cfdf3...Linus Torvalds15 years
v2.6.34-rc2commit 220bf991b0...Linus Torvalds15 years
v2.6.33.1commit dbdafe5ccf...Greg Kroah-Hartman15 years
v2.6.34-rc1commit 57d54889cd...Linus Torvalds16 years
v2.6.33commit 60b341b778...Linus Torvalds16 years
v2.6.33-rc8commit 724e6d3fe8...Linus Torvalds16 years
v2.6.33-rc7commit 29275254ca...Linus Torvalds16 years
v2.6.33-rc6commit abe94c756c...Linus Torvalds16 years
v2.6.33-rc5commit 92dcffb916...Linus Torvalds16 years
v2.6.33-rc4commit 7284ce6c9f...Linus Torvalds16 years
v2.6.33-rc3commit 74d2e4f8d7...Linus Torvalds16 years
v2.6.33-rc2commit 6b7b284958...Linus Torvalds16 years
v2.6.33-rc1commit 55639353a0...Linus Torvalds16 years
v2.6.32commit 22763c5cf3...Linus Torvalds16 years
v2.6.32-rc8commit 648f4e3e50...Linus Torvalds16 years
v2.6.32-rc7commit 156171c71a...Linus Torvalds16 years
v2.6.32-rc6commit b419148e56...Linus Torvalds16 years
v2.6.32-rc5commit 012abeea66...Linus Torvalds16 years
v2.6.32-rc4commit 161291396e...Linus Torvalds16 years
v2.6.32-rc3commit 374576a8b6...Linus Torvalds16 years
v2.6.32-rc1commit 17d857be64...Linus Torvalds16 years
v2.6.32-rc2commit 17d857be64...Linus Torvalds16 years
v2.6.31commit 74fca6a428...Linus Torvalds16 years
v2.6.31-rc9commit e07cccf404...Linus Torvalds16 years
v2.6.31-rc8commit 326ba5010a...Linus Torvalds16 years
v2.6.31-rc7commit 422bef879e...Linus Torvalds16 years
v2.6.31-rc6commit 64f1607ffb...Linus Torvalds16 years
v2.6.31-rc5commit ed680c4ad4...Linus Torvalds16 years
v2.6.31-rc4commit 4be3bd7849...Linus Torvalds16 years
v2.6.31-rc3commit 6847e154e3...Linus Torvalds16 years
v2.6.31-rc2commit 8e4a718ff3...Linus Torvalds16 years
v2.6.31-rc1commit 28d0325ce6...Linus Torvalds16 years
v2.6.30commit 07a2039b8e...Linus Torvalds16 years
v2.6.30-rc8commit 9fa7eb283c...Linus Torvalds16 years
v2.6.30-rc7commit 59a3759d0f...Linus Torvalds16 years
v2.6.30-rc6commit 1406de8e11...Linus Torvalds16 years
v2.6.30-rc5commit 091bf7624d...Linus Torvalds16 years
v2.6.30-rc4commit 091438dd56...Linus Torvalds16 years
v2.6.30-rc3commit 0910697403...Linus Torvalds16 years
v2.6.30-rc2commit 0882e8dd3a...Linus Torvalds16 years
v2.6.30-rc1commit 577c9c456f...Linus Torvalds16 years
v2.6.29commit 8e0ee43bc2...Linus Torvalds16 years
v2.6.29-rc8commit 041b62374c...Linus Torvalds17 years
v2.6.29-rc7commit fec6c6fec3...Linus Torvalds17 years
v2.6.29-rc6commit 20f4d6c3a2...Linus Torvalds17 years
v2.6.29-rc5commit d2f8d7ee1a...Linus Torvalds17 years
v2.6.29-rc4commit 8e4921515c...Linus Torvalds17 years
v2.6.29-rc3commit 18e352e4a7...Linus Torvalds17 years
v2.6.29-rc2commit 1de9e8e70f...Linus Torvalds17 years
v2.6.29-rc1commit c59765042f...Linus Torvalds17 years
v2.6.28commit 4a6908a3a0...Linus Torvalds17 years
v2.6.28-rc9commit 929096fe9f...Linus Torvalds17 years
v2.6.28-rc8commit 8b1fae4e42...Linus Torvalds17 years
v2.6.28-rc7commit 061e41fdb5...Linus Torvalds17 years
v2.6.28-rc6commit 13d428afc0...Linus Torvalds17 years
v2.6.28-rc5commit 9bf1a2445f...Linus Torvalds17 years
v2.6.28-rc4commit f7160c7573...Linus Torvalds17 years
v2.6.28-rc3commit 45beca08dd...Linus Torvalds17 years
v2.6.28-rc2commit 0173a3265b...Linus Torvalds17 years
v2.6.28-rc1commit 57f8f7b60d...Linus Torvalds17 years
v2.6.27commit 3fa8749e58...Linus Torvalds17 years
v2.6.27-rc9commit 4330ed8ed4...Linus Torvalds17 years
v2.6.27-rc8commit 94aca1dac6...Linus Torvalds17 years
v2.6.27-rc7commit 72d31053f6...Linus Torvalds17 years
v2.6.27-rc6commit adee14b2e1...Linus Torvalds17 years
v2.6.27-rc5commit 24342c34a0...Linus Torvalds17 years
v2.6.27-rc4commit 6a55617ed5...Linus Torvalds17 years
v2.6.27-rc3commit 30a2f3c60a...Linus Torvalds17 years
v2.6.27-rc2commit 0967d61ea0...Linus Torvalds17 years
v2.6.27-rc1commit 6e86841d05...Linus Torvalds17 years
v2.6.26commit bce7f793da...Linus Torvalds17 years
v2.6.26-rc9commit b7279469d6...Linus Torvalds17 years
v2.6.26-rc8commit 543cf4cb3f...Linus Torvalds17 years
v2.6.26-rc7commit d70ac829b7...Linus Torvalds17 years
v2.6.26-rc6commit 5dd34572ad...Linus Torvalds17 years
v2.6.26-rc5commit 53c8ba9540...Linus Torvalds17 years
v2.6.26-rc4commit e490517a03...Linus Torvalds17 years
v2.6.26-rc3commit b8291ad07a...Linus Torvalds17 years
v2.6.26-rc2commit 492c2e476e...Linus Torvalds17 years
v2.6.26-rc1commit 2ddcca36c8...Linus Torvalds17 years
v2.6.25commit 4b119e21d0...Linus Torvalds17 years
v2.6.25-rc9commit 120dd64cac...Linus Torvalds17 years
v2.6.25-rc8commit 0e81a8ae37...Linus Torvalds17 years
v2.6.25-rc7commit 05dda977f2...Linus Torvalds17 years
v2.6.25-rc6commit a978b30af3...Linus Torvalds17 years
v2.6.25-rc5commit cdeeeae056...Linus Torvalds18 years
v2.6.25-rc4commit 29e8c3c304...Linus Torvalds18 years
v2.6.25-rc3commit bfa274e243...Linus Torvalds18 years
v2.6.25-rc2commit 101142c37b...Linus Torvalds18 years
v2.6.25-rc1commit 19af35546d...Linus Torvalds18 years
v2.6.24commit 49914084e7...Linus Torvalds18 years
v2.6.24-rc8commit cbd9c88369...Linus Torvalds18 years
v2.6.24-rc7commit 3ce5445046...Linus Torvalds18 years
v2.6.24-rc6commit ea67db4cdb...Linus Torvalds18 years
v2.6.24-rc5commit 82d29bf6dc...Linus Torvalds18 years
v2.6.24-rc4commit 09b56adc98...Linus Torvalds18 years
v2.6.24-rc3commit d9f8bcbf67...Linus Torvalds18 years
v2.6.24-rc2commit dbeeb816e8...Linus Torvalds18 years
v2.6.24-rc1commit c9927c2bf4...Linus Torvalds18 years
v2.6.23commit bbf25010f1...Linus Torvalds18 years
v2.6.23-rc9commit 3146b39c18...Linus Torvalds18 years
v2.6.23-rc8commit 4942de4a0e...Linus Torvalds18 years
v2.6.23-rc7commit 81cfe79b9c...Linus Torvalds18 years
v2.6.23-rc6commit 0d4cbb5e7f...Linus Torvalds18 years
v2.6.23-rc5commit 40ffbfad6b...Linus Torvalds18 years
v2.6.23-rc4commit b07d68b5ca...Linus Torvalds18 years
v2.6.23-rc3commit 39d3520c92...Linus Torvalds18 years
v2.6.23-rc2commit d4ac2477fa...Linus Torvalds18 years
v2.6.23-rc1commit f695baf2df...Linus Torvalds18 years
v2.6.22commit 7dcca30a32...Linus Torvalds18 years
v2.6.22-rc7commit a38d6181ff...Linus Torvalds18 years
v2.6.22-rc6commit 189548642c...Linus Torvalds18 years
v2.6.22-rc5commit 188e1f81ba...Linus Torvalds18 years
v2.6.22-rc4commit 5ecd3100e6...Linus Torvalds18 years
v2.6.22-rc3commit c420bc9f09...Linus Torvalds18 years
v2.6.22-rc2commit 55b637c6a0...Linus Torvalds18 years
v2.6.22-rc1commit 39403865d2...Linus Torvalds18 years
v2.6.21commit de46c33745...Linus Torvalds18 years
v2.6.21-rc7commit 94a05509a9...Linus Torvalds18 years
v2.6.21-rc6commit a21bd69e15...Linus Torvalds18 years
v2.6.21-rc5commit e0f2e3a06b...Linus Torvalds18 years
v2.6.21-rc4commit db98e0b434...Linus Torvalds19 years
v2.6.21-rc3commit 08e15e81a4...Linus Torvalds19 years
v2.6.21-rc2commit 606135a308...Linus Torvalds19 years
v2.6.21-rc1commit c8f71b01a5...Linus Torvalds19 years
v2.6.20commit 62d0cfcb27...Linus Torvalds19 years
v2.6.20-rc7commit f56df2f4db...Linus Torvalds19 years
v2.6.20-rc6commit 99abfeafb5...Linus Torvalds19 years
v2.6.20-rc5commit a8b3485287...Linus Torvalds19 years
v2.6.20-rc4commit bf81b46482...Linus Torvalds19 years
v2.6.20-rc3commit 669df1b478...Linus Torvalds19 years
v2.6.20-rc2commit 3bf8ba38f3...Linus Torvalds19 years
v2.6.20-rc1commit cc016448b0...Linus Torvalds19 years
v2.6.19commit 0215ffb08c...Linus Torvalds19 years
v2.6.19-rc6commit 44597f65f6...Linus Torvalds19 years
v2.6.19-rc5commit 80c2188127...Linus Torvalds19 years
v2.6.19-rc4commit ae99a78af3...Linus Torvalds19 years
v2.6.19-rc3commit 7059abedd2...Linus Torvalds19 years
v2.6.19-rc2commit b4bd8c6643...Linus Torvalds19 years
v2.6.19-rc1commit d223a60106...Linus Torvalds19 years
v2.6.18commit e478bec0ba...Linus Torvalds19 years
v2.6.18-rc7commit 95064a75eb...Linus Torvalds19 years
v2.6.18-rc6commit c336923b66...Linus Torvalds19 years
v2.6.18-rc5commit 60d4684068...Linus Torvalds19 years
v2.6.18-rc4commit 9f737633e6...Linus Torvalds19 years
v2.6.18-rc3commit b6ff50833a...Linus Torvalds19 years
v2.6.18-rc2commit 82d6897fef...Linus Torvalds19 years
v2.6.18-rc1commit 120bda20c6...Linus Torvalds19 years
v2.6.17commit 427abfa28a...Linus Torvalds19 years
v2.6.17-rc6commit 1def630a6a...Linus Torvalds19 years
v2.6.17-rc5commit a8bd60705a...Linus Torvalds19 years
v2.6.17-rc4commit d8c3291c73...Linus Torvalds19 years
v2.6.17-rc3commit 2be4d50295...Linus Torvalds19 years
v2.6.17-rc2commit 8bbde0e6d5...Linus Torvalds19 years
v2.6.17-rc1commit 6246b6128b...Linus Torvalds19 years
v2.6.16commit 7705a8792b...Linus Torvalds19 years
v2.6.16-rc6commit 535744878e...Linus Torvalds20 years
v2.6.16-rc5commit b9a33cebac...Linus Torvalds20 years
v2.6.16-rc4commit bd71c2b174...Linus Torvalds20 years
v2.6.16-rc3commit e9bb4c9929...Linus Torvalds20 years
v2.6.16-rc2commit 826eeb53a6...Linus Torvalds20 years
v2.6.16-rc1commit 2664b25051...Linus Torvalds20 years
v2.6.15commit 88026842b0...Linus Torvalds20 years
v2.6.15-rc7commit f89f5948fc...Linus Torvalds20 years
v2.6.15-rc6commit df7addbb45...Linus Torvalds20 years
v2.6.15-rc5commit 436b0f76f2...Linus Torvalds20 years
v2.6.15-rc4commit 5666c0947e...Linus Torvalds20 years
v2.6.15-rc3commit 624f54be20...Linus Torvalds20 years
v2.6.15-rc2commit 3bedff1d73...Linus Torvalds20 years
v2.6.15-rc1commit cd52d1ee9a...Linus Torvalds20 years
v2.6.14commit 741b2252a5...Linus Torvalds20 years
v2.6.14-rc5commit 93918e9afc...Linus Torvalds20 years
v2.6.14-rc4commit 907a426179...Linus Torvalds20 years
v2.6.14-rc3commit 1c9426e8a5...Linus Torvalds20 years
v2.6.14-rc2commit 676d55ae30...Linus Torvalds20 years
v2.6.14-rc1commit 2f4ba45a75...Linus Torvalds20 years
v2.6.13commit 02b3e4e2d7...Linus Torvalds20 years
v2.6.13-rc7commit 0572e3da3f...Linus Torvalds20 years
v2.6.13-rc6commit 6fc32179de...Linus Torvalds20 years
v2.6.13-rc5commit 9a351e30d7...Linus Torvalds20 years
v2.6.13-rc4commit 6395352334...Linus Torvalds20 years
v2.6.11tree c39ae07f39...
v2.6.11-treetree c39ae07f39...
v2.6.12commit 9ee1c939d1...
v2.6.12-rc2commit 1da177e4c3...
v2.6.12-rc3commit a2755a80f4...
v2.6.12-rc4commit 88d7bd8cb9...
v2.6.12-rc5commit 2a24ab628a...
v2.6.12-rc6commit 7cef5677ef...
v2.6.13-rc1commit 4c91aedb75...
v2.6.13-rc2commit a18bcb7450...
v2.6.13-rc3commit c32511e271...
instead of the DPT "Array Group" feature. * * Multiple ISA, EISA and PCI boards can be configured in the same system. * It is suggested to put all the EISA boards on the same IRQ level, all * the PCI boards on another IRQ level, while ISA boards cannot share * interrupts. * * If you configure multiple boards on the same IRQ, the interrupt must * be _level_ triggered (not _edge_ triggered). * * This driver detects EATA boards by probes at fixed port addresses, * so no BIOS32 or PCI BIOS support is required. * The suggested way to detect a generic EATA PCI board is to force on it * any unused EISA address, even if there are other controllers on the EISA * bus, or even if you system has no EISA bus at all. * Do not force any ISA address on EATA PCI boards. * * If PCI bios support is configured into the kernel, BIOS32 is used to * include in the list of i/o ports to be probed all the PCI SCSI controllers. * * Due to a DPT BIOS "feature", it might not be possible to force an EISA * address on more than a single DPT PCI board, so in this case you have to * let the PCI BIOS assign the addresses. * * The sequence of detection probes is: * * - ISA 0x1F0; * - PCI SCSI controllers (only if BIOS32 is available); * - EISA/PCI 0x1C88 through 0xFC88 (corresponding to EISA slots 1 to 15); * - ISA 0x170, 0x230, 0x330. * * The above list of detection probes can be totally replaced by the * boot command line option: "eata=port0,port1,port2,...", where the * port0, port1... arguments are ISA/EISA/PCI addresses to be probed. * For example using "eata=0x7410,0x7450,0x230", the driver probes * only the two PCI addresses 0x7410 and 0x7450 and the ISA address 0x230, * in this order; "eata=0" totally disables this driver. * * After the optional list of detection probes, other possible command line * options are: * * et:y force use of extended translation (255 heads, 63 sectors); * et:n use disk geometry detected by scsicam_bios_param; * rs:y reverse scan order while detecting PCI boards; * rs:n use BIOS order while detecting PCI boards; * lc:y enables linked commands; * lc:n disables linked commands; * tm:0 disables tagged commands (same as tc:n); * tm:1 use simple queue tags (same as tc:y); * tm:2 use ordered queue tags (same as tc:2); * mq:xx set the max queue depth to the value xx (2 <= xx <= 32). * * The default value is: "eata=lc:n,mq:16,tm:0,et:n,rs:n". * An example using the list of detection probes could be: * "eata=0x7410,0x230,lc:y,tm:2,mq:4,et:n". * * When loading as a module, parameters can be specified as well. * The above example would be (use 1 in place of y and 0 in place of n): * * modprobe eata io_port=0x7410,0x230 linked_comm=1 \ * max_queue_depth=4 ext_tran=0 tag_mode=2 \ * rev_scan=1 * * ---------------------------------------------------------------------------- * In this implementation, linked commands are designed to work with any DISK * or CD-ROM, since this linking has only the intent of clustering (time-wise) * and reordering by elevator sorting commands directed to each device, * without any relation with the actual SCSI protocol between the controller * and the device. * If Q is the queue depth reported at boot time for each device (also named * cmds/lun) and Q > 2, whenever there is already an active command to the * device all other commands to the same device (up to Q-1) are kept waiting * in the elevator sorting queue. When the active command completes, the * commands in this queue are sorted by sector address. The sort is chosen * between increasing or decreasing by minimizing the seek distance between * the sector of the commands just completed and the sector of the first * command in the list to be sorted. * Trivial math assures that the unsorted average seek distance when doing * random seeks over S sectors is S/3. * When (Q-1) requests are uniformly distributed over S sectors, the average * distance between two adjacent requests is S/((Q-1) + 1), so the sorted * average seek distance for (Q-1) random requests over S sectors is S/Q. * The elevator sorting hence divides the seek distance by a factor Q/3. * The above pure geometric remarks are valid in all cases and the * driver effectively reduces the seek distance by the predicted factor * when there are Q concurrent read i/o operations on the device, but this * does not necessarily results in a noticeable performance improvement: * your mileage may vary.... * * Note: command reordering inside a batch of queued commands could cause * wrong results only if there is at least one write request and the * intersection (sector-wise) of all requests is not empty. * When the driver detects a batch including overlapping requests * (a really rare event) strict serial (pid) order is enforced. * ---------------------------------------------------------------------------- * The extended translation option (et:y) is useful when using large physical * disks/arrays. It could also be useful when switching between Adaptec boards * and DPT boards without reformatting the disk. * When a boot disk is partitioned with extended translation, in order to * be able to boot it with a DPT board is could be necessary to add to * lilo.conf additional commands as in the following example: * * fix-table * disk=/dev/sda bios=0x80 sectors=63 heads=128 cylindres=546 * * where the above geometry should be replaced with the one reported at * power up by the DPT controller. * ---------------------------------------------------------------------------- * * The boards are named EATA0, EATA1,... according to the detection order. * * In order to support multiple ISA boards in a reliable way, * the driver sets host->wish_block = 1 for all ISA boards. */ #include <linux/string.h> #include <linux/kernel.h> #include <linux/ioport.h> #include <linux/delay.h> #include <linux/proc_fs.h> #include <linux/blkdev.h> #include <linux/interrupt.h> #include <linux/stat.h> #include <linux/pci.h> #include <linux/init.h> #include <linux/ctype.h> #include <linux/spinlock.h> #include <linux/dma-mapping.h> #include <asm/byteorder.h> #include <asm/dma.h> #include <asm/io.h> #include <asm/irq.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_device.h> #include <scsi/scsi_host.h> #include <scsi/scsi_tcq.h> #include <scsi/scsicam.h> static int eata2x_detect(struct scsi_host_template *); static int eata2x_release(struct Scsi_Host *); static int eata2x_queuecommand(struct scsi_cmnd *, void (*done) (struct scsi_cmnd *)); static int eata2x_eh_abort(struct scsi_cmnd *); static int eata2x_eh_host_reset(struct scsi_cmnd *); static int eata2x_bios_param(struct scsi_device *, struct block_device *, sector_t, int *); static int eata2x_slave_configure(struct scsi_device *); static struct scsi_host_template driver_template = { .name = "EATA/DMA 2.0x rev. 8.10.00 ", .detect = eata2x_detect, .release = eata2x_release, .queuecommand = eata2x_queuecommand, .eh_abort_handler = eata2x_eh_abort, .eh_host_reset_handler = eata2x_eh_host_reset, .bios_param = eata2x_bios_param, .slave_configure = eata2x_slave_configure, .this_id = 7, .unchecked_isa_dma = 1, .use_clustering = ENABLE_CLUSTERING }; #if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD) #error "Adjust your <asm/byteorder.h> defines" #endif /* Subversion values */ #define ISA 0 #define ESA 1 #undef FORCE_CONFIG #undef DEBUG_LINKED_COMMANDS #undef DEBUG_DETECT #undef DEBUG_PCI_DETECT #undef DEBUG_INTERRUPT #undef DEBUG_RESET #undef DEBUG_GENERATE_ERRORS #undef DEBUG_GENERATE_ABORTS #undef DEBUG_GEOMETRY #define MAX_ISA 4 #define MAX_VESA 0 #define MAX_EISA 15 #define MAX_PCI 16 #define MAX_BOARDS (MAX_ISA + MAX_VESA + MAX_EISA + MAX_PCI) #define MAX_CHANNEL 4 #define MAX_LUN 32 #define MAX_TARGET 32 #define MAX_MAILBOXES 64 #define MAX_SGLIST 64 #define MAX_LARGE_SGLIST 122 #define MAX_INTERNAL_RETRIES 64 #define MAX_CMD_PER_LUN 2 #define MAX_TAGGED_CMD_PER_LUN (MAX_MAILBOXES - MAX_CMD_PER_LUN) #define SKIP ULONG_MAX #define FREE 0 #define IN_USE 1 #define LOCKED 2 #define IN_RESET 3 #define IGNORE 4 #define READY 5 #define ABORTING 6 #define NO_DMA 0xff #define MAXLOOP 10000 #define TAG_DISABLED 0 #define TAG_SIMPLE 1 #define TAG_ORDERED 2 #define REG_CMD 7 #define REG_STATUS 7 #define REG_AUX_STATUS 8 #define REG_DATA 0 #define REG_DATA2 1 #define REG_SEE 6 #define REG_LOW 2 #define REG_LM 3 #define REG_MID 4 #define REG_MSB 5 #define REGION_SIZE 9UL #define MAX_ISA_ADDR 0x03ff #define MIN_EISA_ADDR 0x1c88 #define MAX_EISA_ADDR 0xfc88 #define BSY_ASSERTED 0x80 #define DRQ_ASSERTED 0x08 #define ABSY_ASSERTED 0x01 #define IRQ_ASSERTED 0x02 #define READ_CONFIG_PIO 0xf0 #define SET_CONFIG_PIO 0xf1 #define SEND_CP_PIO 0xf2 #define RECEIVE_SP_PIO 0xf3 #define TRUNCATE_XFR_PIO 0xf4 #define RESET_PIO 0xf9 #define READ_CONFIG_DMA 0xfd #define SET_CONFIG_DMA 0xfe #define SEND_CP_DMA 0xff #define ASOK 0x00 #define ASST 0x01 #define YESNO(a) ((a) ? 'y' : 'n') #define TLDEV(type) ((type) == TYPE_DISK || (type) == TYPE_ROM) /* "EATA", in Big Endian format */ #define EATA_SIG_BE 0x45415441 /* Number of valid bytes in the board config structure for EATA 2.0x */ #define EATA_2_0A_SIZE 28 #define EATA_2_0B_SIZE 30 #define EATA_2_0C_SIZE 34 /* Board info structure */ struct eata_info { u_int32_t data_len; /* Number of valid bytes after this field */ u_int32_t sign; /* ASCII "EATA" signature */ #if defined(__BIG_ENDIAN_BITFIELD) unchar version : 4, : 4; unchar haaval : 1, ata : 1, drqvld : 1, dmasup : 1, morsup : 1, trnxfr : 1, tarsup : 1, ocsena : 1; #else unchar : 4, /* unused low nibble */ version : 4; /* EATA version, should be 0x1 */ unchar ocsena : 1, /* Overlap Command Support Enabled */ tarsup : 1, /* Target Mode Supported */ trnxfr : 1, /* Truncate Transfer Cmd NOT Necessary */ morsup : 1, /* More Supported */ dmasup : 1, /* DMA Supported */ drqvld : 1, /* DRQ Index (DRQX) is valid */ ata : 1, /* This is an ATA device */ haaval : 1; /* Host Adapter Address Valid */ #endif ushort cp_pad_len; /* Number of pad bytes after cp_len */ unchar host_addr[4]; /* Host Adapter SCSI ID for channels 3, 2, 1, 0 */ u_int32_t cp_len; /* Number of valid bytes in cp */ u_int32_t sp_len; /* Number of valid bytes in sp */ ushort queue_size; /* Max number of cp that can be queued */ ushort unused; ushort scatt_size; /* Max number of entries in scatter/gather table */ #if defined(__BIG_ENDIAN_BITFIELD) unchar drqx : 2, second : 1, irq_tr : 1, irq : 4; unchar sync; unchar : 4, res1 : 1, large_sg : 1, forcaddr : 1, isaena : 1; unchar max_chan : 3, max_id : 5; unchar max_lun; unchar eisa : 1, pci : 1, idquest : 1, m1 : 1, : 4; #else unchar irq : 4, /* Interrupt Request assigned to this controller */ irq_tr : 1, /* 0 for edge triggered, 1 for level triggered */ second : 1, /* 1 if this is a secondary (not primary) controller */ drqx : 2; /* DRQ Index (0=DMA0, 1=DMA7, 2=DMA6, 3=DMA5) */ unchar sync; /* 1 if scsi target id 7...0 is running sync scsi */ /* Structure extension defined in EATA 2.0B */ unchar isaena : 1, /* ISA i/o addressing is disabled/enabled */ forcaddr : 1, /* Port address has been forced */ large_sg : 1, /* 1 if large SG lists are supported */ res1 : 1, : 4; unchar max_id : 5, /* Max SCSI target ID number */ max_chan : 3; /* Max SCSI channel number on this board */ /* Structure extension defined in EATA 2.0C */ unchar max_lun; /* Max SCSI LUN number */ unchar : 4, m1 : 1, /* This is a PCI with an M1 chip installed */ idquest : 1, /* RAIDNUM returned is questionable */ pci : 1, /* This board is PCI */ eisa : 1; /* This board is EISA */ #endif unchar raidnum; /* Uniquely identifies this HBA in a system */ unchar notused; ushort ipad[247]; }; /* Board config structure */ struct eata_config { ushort len; /* Number of bytes following this field */ #if defined(__BIG_ENDIAN_BITFIELD) unchar : 4, tarena : 1, mdpena : 1, ocena : 1, edis : 1; #else unchar edis : 1, /* Disable EATA interface after config command */ ocena : 1, /* Overlapped Commands Enabled */ mdpena : 1, /* Transfer all Modified Data Pointer Messages */ tarena : 1, /* Target Mode Enabled for this controller */ : 4; #endif unchar cpad[511]; }; /* Returned status packet structure */ struct mssp { #if defined(__BIG_ENDIAN_BITFIELD) unchar eoc : 1, adapter_status : 7; #else unchar adapter_status : 7, /* State related to current command */ eoc : 1; /* End Of Command (1 = command completed) */ #endif unchar target_status; /* SCSI status received after data transfer */ unchar unused[2]; u_int32_t inv_res_len; /* Number of bytes not transferred */ u_int32_t cpp_index; /* Index of address set in cp */ char mess[12]; }; struct sg_list { unsigned int address; /* Segment Address */ unsigned int num_bytes; /* Segment Length */ }; /* MailBox SCSI Command Packet */ struct mscp { #if defined(__BIG_ENDIAN_BITFIELD) unchar din : 1, dout : 1, interp : 1, : 1, sg : 1, reqsen :1, init : 1, sreset : 1; unchar sense_len; unchar unused[3]; unchar : 7, fwnest : 1; unchar : 5, hbaci : 1, iat : 1, phsunit : 1; unchar channel : 3, target : 5; unchar one : 1, dispri : 1, luntar : 1, lun : 5; #else unchar sreset :1, /* SCSI Bus Reset Signal should be asserted */ init :1, /* Re-initialize controller and self test */ reqsen :1, /* Transfer Request Sense Data to addr using DMA */ sg :1, /* Use Scatter/Gather */ :1, interp :1, /* The controller interprets cp, not the target */ dout :1, /* Direction of Transfer is Out (Host to Target) */ din :1; /* Direction of Transfer is In (Target to Host) */ unchar sense_len; /* Request Sense Length */ unchar unused[3]; unchar fwnest : 1, /* Send command to a component of an Array Group */ : 7; unchar phsunit : 1, /* Send to Target Physical Unit (bypass RAID) */ iat : 1, /* Inhibit Address Translation */ hbaci : 1, /* Inhibit HBA Caching for this command */ : 5; unchar target : 5, /* SCSI target ID */ channel : 3; /* SCSI channel number */ unchar lun : 5, /* SCSI logical unit number */ luntar : 1, /* This cp is for Target (not LUN) */ dispri : 1, /* Disconnect Privilege granted */ one : 1; /* 1 */ #endif unchar mess[3]; /* Massage to/from Target */ unchar cdb[12]; /* Command Descriptor Block */ u_int32_t data_len; /* If sg=0 Data Length, if sg=1 sglist length */ u_int32_t cpp_index; /* Index of address to be returned in sp */ u_int32_t data_address; /* If sg=0 Data Address, if sg=1 sglist address */ u_int32_t sp_dma_addr; /* Address where sp is DMA'ed when cp completes */ u_int32_t sense_addr; /* Address where Sense Data is DMA'ed on error */ /* Additional fields begin here. */ struct scsi_cmnd *SCpnt; /* All the cp structure is zero filled by queuecommand except the following CP_TAIL_SIZE bytes, initialized by detect */ dma_addr_t cp_dma_addr; /* dma handle for this cp structure */ struct sg_list *sglist; /* pointer to the allocated SG list */ }; #define CP_TAIL_SIZE (sizeof(struct sglist *) + sizeof(dma_addr_t)) struct hostdata { struct mscp cp[MAX_MAILBOXES]; /* Mailboxes for this board */ unsigned int cp_stat[MAX_MAILBOXES]; /* FREE, IN_USE, LOCKED, IN_RESET */ unsigned int last_cp_used; /* Index of last mailbox used */ unsigned int iocount; /* Total i/o done for this board */ int board_number; /* Number of this board */ char board_name[16]; /* Name of this board */ int in_reset; /* True if board is doing a reset */ int target_to[MAX_TARGET][MAX_CHANNEL]; /* N. of timeout errors on target */ int target_redo[MAX_TARGET][MAX_CHANNEL]; /* If 1 redo i/o on target */ unsigned int retries; /* Number of internal retries */ unsigned long last_retried_pid; /* Pid of last retried command */ unsigned char subversion; /* Bus type, either ISA or EISA/PCI */ unsigned char protocol_rev; /* EATA 2.0 rev., 'A' or 'B' or 'C' */ unsigned char is_pci; /* 1 is bus type is PCI */ struct pci_dev *pdev; /* pdev for PCI bus, NULL otherwise */ struct mssp *sp_cpu_addr; /* cpu addr for DMA buffer sp */ dma_addr_t sp_dma_addr; /* dma handle for DMA buffer sp */ struct mssp sp; /* Local copy of sp buffer */ }; static struct Scsi_Host *sh[MAX_BOARDS]; static const char *driver_name = "EATA"; static char sha[MAX_BOARDS]; static DEFINE_SPINLOCK(driver_lock); /* Initialize num_boards so that ihdlr can work while detect is in progress */ static unsigned int num_boards = MAX_BOARDS; static unsigned long io_port[] = { /* Space for MAX_INT_PARAM ports usable while loading as a module */ SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, /* First ISA */ 0x1f0, /* Space for MAX_PCI ports possibly reported by PCI_BIOS */ SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, SKIP, /* MAX_EISA ports */ 0x1c88, 0x2c88, 0x3c88, 0x4c88, 0x5c88, 0x6c88, 0x7c88, 0x8c88, 0x9c88, 0xac88, 0xbc88, 0xcc88, 0xdc88, 0xec88, 0xfc88, /* Other (MAX_ISA - 1) ports */ 0x170, 0x230, 0x330, /* End of list */ 0x0 }; /* Device is Big Endian */ #define H2DEV(x) cpu_to_be32(x) #define DEV2H(x) be32_to_cpu(x) #define H2DEV16(x) cpu_to_be16(x) #define DEV2H16(x) be16_to_cpu(x) /* But transfer orientation from the 16 bit data register is Little Endian */ #define REG2H(x) le16_to_cpu(x) static irqreturn_t do_interrupt_handler(int, void *, struct pt_regs *); static void flush_dev(struct scsi_device *, unsigned long, struct hostdata *, unsigned int); static int do_trace = 0; static int setup_done = 0; static int link_statistics; static int ext_tran = 0; static int rev_scan = 1; #if defined(CONFIG_SCSI_EATA_TAGGED_QUEUE) static int tag_mode = TAG_SIMPLE; #else static int tag_mode = TAG_DISABLED; #endif #if defined(CONFIG_SCSI_EATA_LINKED_COMMANDS) static int linked_comm = 1; #else static int linked_comm = 0; #endif #if defined(CONFIG_SCSI_EATA_MAX_TAGS) static int max_queue_depth = CONFIG_SCSI_EATA_MAX_TAGS; #else static int max_queue_depth = MAX_CMD_PER_LUN; #endif #if defined(CONFIG_ISA) static int isa_probe = 1; #else static int isa_probe = 0; #endif #if defined(CONFIG_EISA) static int eisa_probe = 1; #else static int eisa_probe = 0; #endif #if defined(CONFIG_PCI) static int pci_probe = 1; #else static int pci_probe = 0; #endif #define MAX_INT_PARAM 10 #define MAX_BOOT_OPTIONS_SIZE 256 static char boot_options[MAX_BOOT_OPTIONS_SIZE]; #if defined(MODULE) #include <linux/module.h> #include <linux/moduleparam.h> module_param_string(eata, boot_options, MAX_BOOT_OPTIONS_SIZE, 0); MODULE_PARM_DESC(eata, " equivalent to the \"eata=...\" kernel boot option." " Example: modprobe eata \"eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n\""); MODULE_AUTHOR("Dario Ballabio"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("EATA/DMA SCSI Driver"); #endif static int eata2x_slave_configure(struct scsi_device *dev) { int tqd, utqd; char *tag_suffix, *link_suffix; utqd = MAX_CMD_PER_LUN; tqd = max_queue_depth; if (TLDEV(dev->type) && dev->tagged_supported) { if (tag_mode == TAG_SIMPLE) { scsi_adjust_queue_depth(dev, MSG_SIMPLE_TAG, tqd); tag_suffix = ", simple tags"; } else if (tag_mode == TAG_ORDERED) { scsi_adjust_queue_depth(dev, MSG_ORDERED_TAG, tqd); tag_suffix = ", ordered tags"; } else { scsi_adjust_queue_depth(dev, 0, tqd); tag_suffix = ", no tags"; } } else if (TLDEV(dev->type) && linked_comm) { scsi_adjust_queue_depth(dev, 0, tqd); tag_suffix = ", untagged"; } else { scsi_adjust_queue_depth(dev, 0, utqd); tag_suffix = ""; } if (TLDEV(dev->type) && linked_comm && dev->queue_depth > 2) link_suffix = ", sorted"; else if (TLDEV(dev->type)) link_suffix = ", unsorted"; else link_suffix = ""; sdev_printk(KERN_INFO, dev, "cmds/lun %d%s%s.\n", dev->queue_depth, link_suffix, tag_suffix); return 0; } static int wait_on_busy(unsigned long iobase, unsigned int loop) { while (inb(iobase + REG_AUX_STATUS) & ABSY_ASSERTED) { udelay(1L); if (--loop == 0) return 1; } return 0; } static int do_dma(unsigned long iobase, unsigned long addr, unchar cmd) { unsigned char *byaddr; unsigned long devaddr; if (wait_on_busy(iobase, (addr ? MAXLOOP * 100 : MAXLOOP))) return 1; if (addr) { devaddr = H2DEV(addr); byaddr = (unsigned char *)&devaddr; outb(byaddr[3], iobase + REG_LOW); outb(byaddr[2], iobase + REG_LM); outb(byaddr[1], iobase + REG_MID); outb(byaddr[0], iobase + REG_MSB); } outb(cmd, iobase + REG_CMD); return 0; } static int read_pio(unsigned long iobase, ushort * start, ushort * end) { unsigned int loop = MAXLOOP; ushort *p; for (p = start; p <= end; p++) { while (!(inb(iobase + REG_STATUS) & DRQ_ASSERTED)) { udelay(1L); if (--loop == 0) return 1; } loop = MAXLOOP; *p = REG2H(inw(iobase)); } return 0; } static struct pci_dev *get_pci_dev(unsigned long port_base) { #if defined(CONFIG_PCI) unsigned int addr; struct pci_dev *dev = NULL; while ((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) { addr = pci_resource_start(dev, 0); #if defined(DEBUG_PCI_DETECT) printk("%s: get_pci_dev, bus %d, devfn 0x%x, addr 0x%x.\n", driver_name, dev->bus->number, dev->devfn, addr); #endif /* we are in so much trouble for a pci hotplug system with this driver * anyway, so doing this at least lets people unload the driver and not * cause memory problems, but in general this is a bad thing to do (this * driver needs to be converted to the proper PCI api someday... */ pci_dev_put(dev); if (addr + PCI_BASE_ADDRESS_0 == port_base) return dev; } #endif /* end CONFIG_PCI */ return NULL; } static void enable_pci_ports(void) { #if defined(CONFIG_PCI) struct pci_dev *dev = NULL; while ((dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) { #if defined(DEBUG_PCI_DETECT) printk("%s: enable_pci_ports, bus %d, devfn 0x%x.\n", driver_name, dev->bus->number, dev->devfn); #endif if (pci_enable_device(dev)) printk ("%s: warning, pci_enable_device failed, bus %d devfn 0x%x.\n", driver_name, dev->bus->number, dev->devfn); } #endif /* end CONFIG_PCI */ } static int port_detect(unsigned long port_base, unsigned int j, struct scsi_host_template *tpnt) { unsigned char irq, dma_channel, subversion, i, is_pci = 0; unsigned char protocol_rev; struct eata_info info; char *bus_type, dma_name[16]; struct pci_dev *pdev; /* Allowed DMA channels for ISA (0 indicates reserved) */ unsigned char dma_channel_table[4] = { 5, 6, 7, 0 }; struct Scsi_Host *shost; struct hostdata *ha; char name[16]; sprintf(name, "%s%d", driver_name, j); if (!request_region(port_base, REGION_SIZE, driver_name)) { #if defined(DEBUG_DETECT) printk("%s: address 0x%03lx in use, skipping probe.\n", name, port_base); #endif goto fail; } spin_lock_irq(&driver_lock); if (do_dma(port_base, 0, READ_CONFIG_PIO)) { #if defined(DEBUG_DETECT) printk("%s: detect, do_dma failed at 0x%03lx.\n", name, port_base); #endif goto freelock; } /* Read the info structure */ if (read_pio(port_base, (ushort *) & info, (ushort *) & info.ipad[0])) { #if defined(DEBUG_DETECT) printk("%s: detect, read_pio failed at 0x%03lx.\n", name, port_base); #endif goto freelock; } info.data_len = DEV2H(info.data_len); info.sign = DEV2H(info.sign); info.cp_pad_len = DEV2H16(info.cp_pad_len); info.cp_len = DEV2H(info.cp_len); info.sp_len = DEV2H(info.sp_len); info.scatt_size = DEV2H16(info.scatt_size); info.queue_size = DEV2H16(info.queue_size); /* Check the controller "EATA" signature */ if (info.sign != EATA_SIG_BE) { #if defined(DEBUG_DETECT) printk("%s: signature 0x%04x discarded.\n", name, info.sign); #endif goto freelock; } if (info.data_len < EATA_2_0A_SIZE) { printk ("%s: config structure size (%d bytes) too short, detaching.\n", name, info.data_len); goto freelock; } else if (info.data_len == EATA_2_0A_SIZE) protocol_rev = 'A'; else if (info.data_len == EATA_2_0B_SIZE) protocol_rev = 'B'; else protocol_rev = 'C'; if (protocol_rev != 'A' && info.forcaddr) { printk("%s: warning, port address has been forced.\n", name); bus_type = "PCI"; is_pci = 1; subversion = ESA; } else if (port_base > MAX_EISA_ADDR || (protocol_rev == 'C' && info.pci)) { bus_type = "PCI"; is_pci = 1; subversion = ESA; } else if (port_base >= MIN_EISA_ADDR || (protocol_rev == 'C' && info.eisa)) { bus_type = "EISA"; subversion = ESA; } else if (protocol_rev == 'C' && !info.eisa && !info.pci) { bus_type = "ISA"; subversion = ISA; } else if (port_base > MAX_ISA_ADDR) { bus_type = "PCI"; is_pci = 1; subversion = ESA; } else { bus_type = "ISA"; subversion = ISA; } if (!info.haaval || info.ata) { printk ("%s: address 0x%03lx, unusable %s board (%d%d), detaching.\n", name, port_base, bus_type, info.haaval, info.ata); goto freelock; } if (info.drqvld) { if (subversion == ESA) printk("%s: warning, weird %s board using DMA.\n", name, bus_type); subversion = ISA; dma_channel = dma_channel_table[3 - info.drqx]; } else { if (subversion == ISA) printk("%s: warning, weird %s board not using DMA.\n", name, bus_type); subversion = ESA; dma_channel = NO_DMA; } if (!info.dmasup) printk("%s: warning, DMA protocol support not asserted.\n", name); irq = info.irq; if (subversion == ESA && !info.irq_tr) printk ("%s: warning, LEVEL triggering is suggested for IRQ %u.\n", name, irq); if (is_pci) { pdev = get_pci_dev(port_base); if (!pdev) printk ("%s: warning, failed to get pci_dev structure.\n", name); } else pdev = NULL; if (pdev && (irq != pdev->irq)) { printk("%s: IRQ %u mapped to IO-APIC IRQ %u.\n", name, irq, pdev->irq); irq = pdev->irq; } /* Board detected, allocate its IRQ */ if (request_irq(irq, do_interrupt_handler, IRQF_DISABLED | ((subversion == ESA) ? IRQF_SHARED : 0), driver_name, (void *)&sha[j])) { printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq); goto freelock; } if (subversion == ISA && request_dma(dma_channel, driver_name)) { printk("%s: unable to allocate DMA channel %u, detaching.\n", name, dma_channel); goto freeirq; } #if defined(FORCE_CONFIG) { struct eata_config *cf; dma_addr_t cf_dma_addr; cf = pci_alloc_consistent(pdev, sizeof(struct eata_config), &cf_dma_addr); if (!cf) { printk ("%s: config, pci_alloc_consistent failed, detaching.\n", name); goto freedma; } /* Set board configuration */ memset((char *)cf, 0, sizeof(struct eata_config)); cf->len = (ushort) H2DEV16((ushort) 510); cf->ocena = 1; if (do_dma(port_base, cf_dma_addr, SET_CONFIG_DMA)) { printk ("%s: busy timeout sending configuration, detaching.\n", name); pci_free_consistent(pdev, sizeof(struct eata_config), cf, cf_dma_addr); goto freedma; } } #endif spin_unlock_irq(&driver_lock); sh[j] = shost = scsi_register(tpnt, sizeof(struct hostdata)); spin_lock_irq(&driver_lock); if (shost == NULL) { printk("%s: unable to register host, detaching.\n", name); goto freedma; } shost->io_port = port_base; shost->unique_id = port_base; shost->n_io_port = REGION_SIZE; shost->dma_channel = dma_channel; shost->irq = irq; shost->sg_tablesize = (ushort) info.scatt_size; shost->this_id = (ushort) info.host_addr[3]; shost->can_queue = (ushort) info.queue_size; shost->cmd_per_lun = MAX_CMD_PER_LUN; ha = (struct hostdata *)shost->hostdata; memset(ha, 0, sizeof(struct hostdata)); ha->subversion = subversion; ha->protocol_rev = protocol_rev; ha->is_pci = is_pci; ha->pdev = pdev; ha->board_number = j; if (ha->subversion == ESA) shost->unchecked_isa_dma = 0; else { unsigned long flags; shost->unchecked_isa_dma = 1; flags = claim_dma_lock(); disable_dma(dma_channel); clear_dma_ff(dma_channel); set_dma_mode(dma_channel, DMA_MODE_CASCADE); enable_dma(dma_channel); release_dma_lock(flags); } strcpy(ha->board_name, name); /* DPT PM2012 does not allow to detect sg_tablesize correctly */ if (shost->sg_tablesize > MAX_SGLIST || shost->sg_tablesize < 2) { printk("%s: detect, wrong n. of SG lists %d, fixed.\n", ha->board_name, shost->sg_tablesize); shost->sg_tablesize = MAX_SGLIST; } /* DPT PM2012 does not allow to detect can_queue correctly */ if (shost->can_queue > MAX_MAILBOXES || shost->can_queue < 2) { printk("%s: detect, wrong n. of mbox %d, fixed.\n", ha->board_name, shost->can_queue); shost->can_queue = MAX_MAILBOXES; } if (protocol_rev != 'A') { if (info.max_chan > 0 && info.max_chan < MAX_CHANNEL) shost->max_channel = info.max_chan; if (info.max_id > 7 && info.max_id < MAX_TARGET) shost->max_id = info.max_id + 1; if (info.large_sg && shost->sg_tablesize == MAX_SGLIST) shost->sg_tablesize = MAX_LARGE_SGLIST; } if (protocol_rev == 'C') { if (info.max_lun > 7 && info.max_lun < MAX_LUN) shost->max_lun = info.max_lun + 1; } if (dma_channel == NO_DMA) sprintf(dma_name, "%s", "BMST"); else sprintf(dma_name, "DMA %u", dma_channel); spin_unlock_irq(&driver_lock); for (i = 0; i < shost->can_queue; i++) ha->cp[i].cp_dma_addr = pci_map_single(ha->pdev, &ha->cp[i], sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL); for (i = 0; i < shost->can_queue; i++) { size_t sz = shost->sg_tablesize *sizeof(struct sg_list); gfp_t gfp_mask = (shost->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC; ha->cp[i].sglist = kmalloc(sz, gfp_mask); if (!ha->cp[i].sglist) { printk ("%s: kmalloc SGlist failed, mbox %d, detaching.\n", ha->board_name, i); goto release; } } if (!(ha->sp_cpu_addr = pci_alloc_consistent(ha->pdev, sizeof(struct mssp), &ha->sp_dma_addr))) { printk("%s: pci_alloc_consistent failed, detaching.\n", ha->board_name); goto release; } if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN) max_queue_depth = MAX_TAGGED_CMD_PER_LUN; if (max_queue_depth < MAX_CMD_PER_LUN) max_queue_depth = MAX_CMD_PER_LUN; if (tag_mode != TAG_DISABLED && tag_mode != TAG_SIMPLE) tag_mode = TAG_ORDERED; if (j == 0) { printk ("EATA/DMA 2.0x: Copyright (C) 1994-2003 Dario Ballabio.\n"); printk ("%s config options -> tm:%d, lc:%c, mq:%d, rs:%c, et:%c, " "ip:%c, ep:%c, pp:%c.\n", driver_name, tag_mode, YESNO(linked_comm), max_queue_depth, YESNO(rev_scan), YESNO(ext_tran), YESNO(isa_probe), YESNO(eisa_probe), YESNO(pci_probe)); } printk("%s: 2.0%c, %s 0x%03lx, IRQ %u, %s, SG %d, MB %d.\n", ha->board_name, ha->protocol_rev, bus_type, (unsigned long)shost->io_port, shost->irq, dma_name, shost->sg_tablesize, shost->can_queue); if (shost->max_id > 8 || shost->max_lun > 8) printk ("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n", ha->board_name, shost->max_id, shost->max_lun); for (i = 0; i <= shost->max_channel; i++) printk("%s: SCSI channel %u enabled, host target ID %d.\n", ha->board_name, i, info.host_addr[3 - i]); #if defined(DEBUG_DETECT) printk("%s: Vers. 0x%x, ocs %u, tar %u, trnxfr %u, more %u, SYNC 0x%x, " "sec. %u, infol %d, cpl %d spl %d.\n", name, info.version, info.ocsena, info.tarsup, info.trnxfr, info.morsup, info.sync, info.second, info.data_len, info.cp_len, info.sp_len); if (protocol_rev == 'B' || protocol_rev == 'C') printk("%s: isaena %u, forcaddr %u, max_id %u, max_chan %u, " "large_sg %u, res1 %u.\n", name, info.isaena, info.forcaddr, info.max_id, info.max_chan, info.large_sg, info.res1); if (protocol_rev == 'C') printk("%s: max_lun %u, m1 %u, idquest %u, pci %u, eisa %u, " "raidnum %u.\n", name, info.max_lun, info.m1, info.idquest, info.pci, info.eisa, info.raidnum); #endif if (ha->pdev) { pci_set_master(ha->pdev); if (pci_set_dma_mask(ha->pdev, DMA_32BIT_MASK)) printk("%s: warning, pci_set_dma_mask failed.\n", ha->board_name); } return 1; freedma: if (subversion == ISA) free_dma(dma_channel); freeirq: free_irq(irq, &sha[j]); freelock: spin_unlock_irq(&driver_lock); release_region(port_base, REGION_SIZE); fail: return 0; release: eata2x_release(shost); return 0; } static void internal_setup(char *str, int *ints) { int i, argc = ints[0]; char *cur = str, *pc; if (argc > 0) { if (argc > MAX_INT_PARAM) argc = MAX_INT_PARAM; for (i = 0; i < argc; i++) io_port[i] = ints[i + 1]; io_port[i] = 0; setup_done = 1; } while (cur && (pc = strchr(cur, ':'))) { int val = 0, c = *++pc; if (c == 'n' || c == 'N') val = 0; else if (c == 'y' || c == 'Y') val = 1; else val = (int)simple_strtoul(pc, NULL, 0); if (!strncmp(cur, "lc:", 3)) linked_comm = val; else if (!strncmp(cur, "tm:", 3)) tag_mode = val; else if (!strncmp(cur, "tc:", 3)) tag_mode = val; else if (!strncmp(cur, "mq:", 3)) max_queue_depth = val; else if (!strncmp(cur, "ls:", 3)) link_statistics = val; else if (!strncmp(cur, "et:", 3)) ext_tran = val; else if (!strncmp(cur, "rs:", 3)) rev_scan = val; else if (!strncmp(cur, "ip:", 3)) isa_probe = val; else if (!strncmp(cur, "ep:", 3)) eisa_probe = val; else if (!strncmp(cur, "pp:", 3)) pci_probe = val; if ((cur = strchr(cur, ','))) ++cur; } return; } static int option_setup(char *str) { int ints[MAX_INT_PARAM]; char *cur = str; int i = 1; while (cur && isdigit(*cur) && i <= MAX_INT_PARAM) { ints[i++] = simple_strtoul(cur, NULL, 0); if ((cur = strchr(cur, ',')) != NULL) cur++; } ints[0] = i - 1; internal_setup(cur, ints); return 1; } static void add_pci_ports(void) { #if defined(CONFIG_PCI) unsigned int addr, k; struct pci_dev *dev = NULL; for (k = 0; k < MAX_PCI; k++) { if (!(dev = pci_get_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) break; if (pci_enable_device(dev)) { #if defined(DEBUG_PCI_DETECT) printk ("%s: detect, bus %d, devfn 0x%x, pci_enable_device failed.\n", driver_name, dev->bus->number, dev->devfn); #endif continue; } addr = pci_resource_start(dev, 0); #if defined(DEBUG_PCI_DETECT) printk("%s: detect, seq. %d, bus %d, devfn 0x%x, addr 0x%x.\n", driver_name, k, dev->bus->number, dev->devfn, addr); #endif /* Order addresses according to rev_scan value */ io_port[MAX_INT_PARAM + (rev_scan ? (MAX_PCI - k) : (1 + k))] = addr + PCI_BASE_ADDRESS_0; } pci_dev_put(dev); #endif /* end CONFIG_PCI */ } static int eata2x_detect(struct scsi_host_template *tpnt) { unsigned int j = 0, k; tpnt->proc_name = "eata2x"; if (strlen(boot_options)) option_setup(boot_options); #if defined(MODULE) /* io_port could have been modified when loading as a module */ if (io_port[0] != SKIP) { setup_done = 1; io_port[MAX_INT_PARAM] = 0; } #endif for (k = MAX_INT_PARAM; io_port[k]; k++) if (io_port[k] == SKIP) continue; else if (io_port[k] <= MAX_ISA_ADDR) { if (!isa_probe) io_port[k] = SKIP; } else if (io_port[k] >= MIN_EISA_ADDR && io_port[k] <= MAX_EISA_ADDR) { if (!eisa_probe) io_port[k] = SKIP; } if (pci_probe) { if (!setup_done) add_pci_ports(); else enable_pci_ports(); } for (k = 0; io_port[k]; k++) { if (io_port[k] == SKIP) continue; if (j < MAX_BOARDS && port_detect(io_port[k], j, tpnt)) j++; } num_boards = j; return j; } static void map_dma(unsigned int i, struct hostdata *ha) { unsigned int k, count, pci_dir; struct scatterlist *sgpnt; struct mscp *cpp; struct scsi_cmnd *SCpnt; cpp = &ha->cp[i]; SCpnt = cpp->SCpnt; pci_dir = SCpnt->sc_data_direction; if (SCpnt->sense_buffer) cpp->sense_addr = H2DEV(pci_map_single(ha->pdev, SCpnt->sense_buffer, sizeof SCpnt->sense_buffer, PCI_DMA_FROMDEVICE)); cpp->sense_len = sizeof SCpnt->sense_buffer; if (!SCpnt->use_sg) { /* If we get here with PCI_DMA_NONE, pci_map_single triggers a BUG() */ if (!SCpnt->request_bufflen) pci_dir = PCI_DMA_BIDIRECTIONAL; if (SCpnt->request_buffer) cpp->data_address = H2DEV(pci_map_single(ha->pdev, SCpnt-> request_buffer, SCpnt-> request_bufflen, pci_dir)); cpp->data_len = H2DEV(SCpnt->request_bufflen); return; } sgpnt = (struct scatterlist *)SCpnt->request_buffer; count = pci_map_sg(ha->pdev, sgpnt, SCpnt->use_sg, pci_dir); for (k = 0; k < count; k++) { cpp->sglist[k].address = H2DEV(sg_dma_address(&sgpnt[k])); cpp->sglist[k].num_bytes = H2DEV(sg_dma_len(&sgpnt[k])); } cpp->sg = 1; cpp->data_address = H2DEV(pci_map_single(ha->pdev, cpp->sglist, SCpnt->use_sg * sizeof(struct sg_list), pci_dir)); cpp->data_len = H2DEV((SCpnt->use_sg * sizeof(struct sg_list))); } static void unmap_dma(unsigned int i, struct hostdata *ha) { unsigned int pci_dir; struct mscp *cpp; struct scsi_cmnd *SCpnt; cpp = &ha->cp[i]; SCpnt = cpp->SCpnt; pci_dir = SCpnt->sc_data_direction; if (DEV2H(cpp->sense_addr)) pci_unmap_single(ha->pdev, DEV2H(cpp->sense_addr), DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE); if (SCpnt->use_sg) pci_unmap_sg(ha->pdev, SCpnt->request_buffer, SCpnt->use_sg, pci_dir); if (!DEV2H(cpp->data_len)) pci_dir = PCI_DMA_BIDIRECTIONAL; if (DEV2H(cpp->data_address)) pci_unmap_single(ha->pdev, DEV2H(cpp->data_address), DEV2H(cpp->data_len), pci_dir); } static void sync_dma(unsigned int i, struct hostdata *ha) { unsigned int pci_dir; struct mscp *cpp; struct scsi_cmnd *SCpnt; cpp = &ha->cp[i]; SCpnt = cpp->SCpnt; pci_dir = SCpnt->sc_data_direction; if (DEV2H(cpp->sense_addr)) pci_dma_sync_single_for_cpu(ha->pdev, DEV2H(cpp->sense_addr), DEV2H(cpp->sense_len), PCI_DMA_FROMDEVICE); if (SCpnt->use_sg) pci_dma_sync_sg_for_cpu(ha->pdev, SCpnt->request_buffer, SCpnt->use_sg, pci_dir); if (!DEV2H(cpp->data_len)) pci_dir = PCI_DMA_BIDIRECTIONAL; if (DEV2H(cpp->data_address)) pci_dma_sync_single_for_cpu(ha->pdev, DEV2H(cpp->data_address), DEV2H(cpp->data_len), pci_dir); } static void scsi_to_dev_dir(unsigned int i, struct hostdata *ha) { unsigned int k; static const unsigned char data_out_cmds[] = { 0x0a, 0x2a, 0x15, 0x55, 0x04, 0x07, 0x18, 0x1d, 0x24, 0x2e, 0x30, 0x31, 0x32, 0x38, 0x39, 0x3a, 0x3b, 0x3d, 0x3f, 0x40, 0x41, 0x4c, 0xaa, 0xae, 0xb0, 0xb1, 0xb2, 0xb6, 0xea, 0x1b, 0x5d }; static const unsigned char data_none_cmds[] = { 0x01, 0x0b, 0x10, 0x11, 0x13, 0x16, 0x17, 0x19, 0x2b, 0x1e, 0x2c, 0xac, 0x2f, 0xaf, 0x33, 0xb3, 0x35, 0x36, 0x45, 0x47, 0x48, 0x49, 0xa9, 0x4b, 0xa5, 0xa6, 0xb5, 0x00 }; struct mscp *cpp; struct scsi_cmnd *SCpnt; cpp = &ha->cp[i]; SCpnt = cpp->SCpnt; if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) { cpp->din = 1; cpp->dout = 0; return; } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) { cpp->din = 0; cpp->dout = 1; return; } else if (SCpnt->sc_data_direction == DMA_NONE) { cpp->din = 0; cpp->dout = 0; return; } if (SCpnt->sc_data_direction != DMA_BIDIRECTIONAL) panic("%s: qcomm, invalid SCpnt->sc_data_direction.\n", ha->board_name); for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++) if (SCpnt->cmnd[0] == data_out_cmds[k]) { cpp->dout = 1; break; } if ((cpp->din = !cpp->dout)) for (k = 0; k < ARRAY_SIZE(data_none_cmds); k++) if (SCpnt->cmnd[0] == data_none_cmds[k]) { cpp->din = 0; break; } } static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, void (*done) (struct scsi_cmnd *)) { struct Scsi_Host *shost = SCpnt->device->host; struct hostdata *ha = (struct hostdata *)shost->hostdata; unsigned int i, k; struct mscp *cpp; if (SCpnt->host_scribble) panic("%s: qcomm, pid %ld, SCpnt %p already active.\n", ha->board_name, SCpnt->pid, SCpnt); /* i is the mailbox number, look for the first free mailbox starting from last_cp_used */ i = ha->last_cp_used + 1; for (k = 0; k < shost->can_queue; k++, i++) { if (i >= shost->can_queue) i = 0; if (ha->cp_stat[i] == FREE) { ha->last_cp_used = i; break; } } if (k == shost->can_queue) { printk("%s: qcomm, no free mailbox.\n", ha->board_name); return 1; } /* Set pointer to control packet structure */ cpp = &ha->cp[i]; memset(cpp, 0, sizeof(struct mscp) - CP_TAIL_SIZE); /* Set pointer to status packet structure, Big Endian format */ cpp->sp_dma_addr = H2DEV(ha->sp_dma_addr); SCpnt->scsi_done = done; cpp->cpp_index = i; SCpnt->host_scribble = (unsigned char *)&cpp->cpp_index; if (do_trace) scmd_printk(KERN_INFO, SCpnt, "qcomm, mbox %d, pid %ld.\n", i, SCpnt->pid); cpp->reqsen = 1; cpp->dispri = 1; #if 0 if (SCpnt->device->type == TYPE_TAPE) cpp->hbaci = 1; #endif cpp->one = 1; cpp->channel = SCpnt->device->channel; cpp->target = SCpnt->device->id; cpp->lun = SCpnt->device->lun; cpp->SCpnt = SCpnt; memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len); /* Use data transfer direction SCpnt->sc_data_direction */ scsi_to_dev_dir(i, ha); /* Map DMA buffers and SG list */ map_dma(i, ha); if (linked_comm && SCpnt->device->queue_depth > 2 && TLDEV(SCpnt->device->type)) { ha->cp_stat[i] = READY; flush_dev(SCpnt->device, SCpnt->request->sector, ha, 0); return 0; } /* Send control packet to the board */ if (do_dma(shost->io_port, cpp->cp_dma_addr, SEND_CP_DMA)) { unmap_dma(i, ha); SCpnt->host_scribble = NULL; scmd_printk(KERN_INFO, SCpnt, "qcomm, pid %ld, adapter busy.\n", SCpnt->pid); return 1; } ha->cp_stat[i] = IN_USE; return 0; } static int eata2x_eh_abort(struct scsi_cmnd *SCarg) { struct Scsi_Host *shost = SCarg->device->host; struct hostdata *ha = (struct hostdata *)shost->hostdata; unsigned int i; if (SCarg->host_scribble == NULL) { scmd_printk(KERN_INFO, SCarg, "abort, pid %ld inactive.\n", SCarg->pid); return SUCCESS; } i = *(unsigned int *)SCarg->host_scribble; scmd_printk(KERN_WARNING, SCarg, "abort, mbox %d, pid %ld.\n", i, SCarg->pid); if (i >= shost->can_queue) panic("%s: abort, invalid SCarg->host_scribble.\n", ha->board_name); if (wait_on_busy(shost->io_port, MAXLOOP)) { printk("%s: abort, timeout error.\n", ha->board_name); return FAILED; } if (ha->cp_stat[i] == FREE) { printk("%s: abort, mbox %d is free.\n", ha->board_name, i); return SUCCESS; } if (ha->cp_stat[i] == IN_USE) { printk("%s: abort, mbox %d is in use.\n", ha->board_name, i); if (SCarg != ha->cp[i].SCpnt) panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n", ha->board_name, i, SCarg, ha->cp[i].SCpnt); if (inb(shost->io_port + REG_AUX_STATUS) & IRQ_ASSERTED) printk("%s: abort, mbox %d, interrupt pending.\n", ha->board_name, i); return FAILED; } if (ha->cp_stat[i] == IN_RESET) { printk("%s: abort, mbox %d is in reset.\n", ha->board_name, i); return FAILED; } if (ha->cp_stat[i] == LOCKED) { printk("%s: abort, mbox %d is locked.\n", ha->board_name, i); return SUCCESS; } if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) { unmap_dma(i, ha); SCarg->result = DID_ABORT << 16; SCarg->host_scribble = NULL; ha->cp_stat[i] = FREE; printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n", ha->board_name, i, SCarg->pid); SCarg->scsi_done(SCarg); return SUCCESS; } panic("%s: abort, mbox %d, invalid cp_stat.\n", ha->board_name, i); } static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) { unsigned int i, time, k, c, limit = 0; int arg_done = 0; struct scsi_cmnd *SCpnt; struct Scsi_Host *shost = SCarg->device->host; struct hostdata *ha = (struct hostdata *)shost->hostdata; scmd_printk(KERN_INFO, SCarg, "reset, enter, pid %ld.\n", SCarg->pid); spin_lock_irq(shost->host_lock); if (SCarg->host_scribble == NULL) printk("%s: reset, pid %ld inactive.\n", ha->board_name, SCarg->pid); if (ha->in_reset) { printk("%s: reset, exit, already in reset.\n", ha->board_name); spin_unlock_irq(shost->host_lock); return FAILED; } if (wait_on_busy(shost->io_port, MAXLOOP)) { printk("%s: reset, exit, timeout error.\n", ha->board_name); spin_unlock_irq(shost->host_lock); return FAILED; } ha->retries = 0; for (c = 0; c <= shost->max_channel; c++) for (k = 0; k < shost->max_id; k++) { ha->target_redo[k][c] = 1; ha->target_to[k][c] = 0; }