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 Elliott12 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 Torvalds16 years
v2.6.33.1commit dbdafe5ccf...Greg Kroah-Hartman16 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 Torvalds18 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 Torvalds20 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...
t bas_cardstate *ucs = cs->hw.bas; int ret; gig_dbg(DEBUG_USBREQ, "-------> HD_READ_ATMESSAGE (%d)", ucs->rcvbuf_size); if (ucs->urb_cmd_in->status == -EINPROGRESS) { dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: URB busy\n"); return -EBUSY; } ucs->dr_cmd_in.bRequestType = IN_VENDOR_REQ; ucs->dr_cmd_in.bRequest = HD_READ_ATMESSAGE; ucs->dr_cmd_in.wValue = 0; ucs->dr_cmd_in.wIndex = 0; ucs->dr_cmd_in.wLength = cpu_to_le16(ucs->rcvbuf_size); usb_fill_control_urb(ucs->urb_cmd_in, ucs->udev, usb_rcvctrlpipe(ucs->udev, 0), (unsigned char*) & ucs->dr_cmd_in, ucs->rcvbuf, ucs->rcvbuf_size, read_ctrl_callback, cs->inbuf); if ((ret = usb_submit_urb(ucs->urb_cmd_in, SLAB_ATOMIC)) != 0) { dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n", get_usb_statmsg(ret)); return ret; } if (timeout > 0) { gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); ucs->timer_cmd_in.expires = jiffies + timeout * HZ / 10; ucs->timer_cmd_in.data = (unsigned long) cs; ucs->timer_cmd_in.function = cmd_in_timeout; add_timer(&ucs->timer_cmd_in); } return 0; } static void stopurbs(struct bas_bc_state *); static int start_cbsend(struct cardstate *); /* set/clear bits in base connection state */ inline static void update_basstate(struct bas_cardstate *ucs, int set, int clear) { unsigned long flags; int state; spin_lock_irqsave(&ucs->lock, flags); state = atomic_read(&ucs->basstate); state &= ~clear; state |= set; atomic_set(&ucs->basstate, state); spin_unlock_irqrestore(&ucs->lock, flags); } /* read_int_callback * USB completion handler for interrupt pipe input * called by the USB subsystem in interrupt context * parameter: * urb USB request block * urb->context = controller state structure */ static void read_int_callback(struct urb *urb, struct pt_regs *regs) { struct cardstate *cs = urb->context; struct bas_cardstate *ucs = cs->hw.bas; struct bc_state *bcs; unsigned long flags; int status; unsigned l; int channel; if (unlikely(!atomic_read(&cs->connected))) { warn("%s: disconnected", __func__); return; } switch (urb->status) { case 0: /* success */ break; case -ENOENT: /* canceled */ case -ECONNRESET: /* canceled (async) */ case -EINPROGRESS: /* pending */ /* ignore silently */ gig_dbg(DEBUG_USBREQ, "%s: %s", __func__, get_usb_statmsg(urb->status)); return; default: /* severe trouble */ dev_warn(cs->dev, "interrupt read: %s\n", get_usb_statmsg(urb->status)); //FIXME corrective action? resubmission always ok? goto resubmit; } l = (unsigned) ucs->int_in_buf[1] + (((unsigned) ucs->int_in_buf[2]) << 8); gig_dbg(DEBUG_USBREQ, "<-------%d: 0x%02x (%u [0x%02x 0x%02x])", urb->actual_length, (int)ucs->int_in_buf[0], l, (int)ucs->int_in_buf[1], (int)ucs->int_in_buf[2]); channel = 0; switch (ucs->int_in_buf[0]) { case HD_DEVICE_INIT_OK: update_basstate(ucs, BS_INIT, 0); break; case HD_READY_SEND_ATDATA: del_timer(&ucs->timer_atrdy); update_basstate(ucs, BS_ATREADY, BS_ATTIMER); start_cbsend(cs); break; case HD_OPEN_B2CHANNEL_ACK: ++channel; case HD_OPEN_B1CHANNEL_ACK: bcs = cs->bcs + channel; update_basstate(ucs, BS_B1OPEN << channel, 0); gigaset_bchannel_up(bcs); break; case HD_OPEN_ATCHANNEL_ACK: update_basstate(ucs, BS_ATOPEN, 0); start_cbsend(cs); break; case HD_CLOSE_B2CHANNEL_ACK: ++channel; case HD_CLOSE_B1CHANNEL_ACK: bcs = cs->bcs + channel; update_basstate(ucs, 0, BS_B1OPEN << channel); stopurbs(bcs->hw.bas); gigaset_bchannel_down(bcs); break; case HD_CLOSE_ATCHANNEL_ACK: update_basstate(ucs, 0, BS_ATOPEN); break; case HD_B2_FLOW_CONTROL: ++channel; case HD_B1_FLOW_CONTROL: bcs = cs->bcs + channel; atomic_add((l - BAS_NORMFRAME) * BAS_CORRFRAMES, &bcs->hw.bas->corrbytes); gig_dbg(DEBUG_ISO, "Flow control (channel %d, sub %d): 0x%02x => %d", channel, bcs->hw.bas->numsub, l, atomic_read(&bcs->hw.bas->corrbytes)); break; case HD_RECEIVEATDATA_ACK: /* AT response ready to be received */ if (!l) { dev_warn(cs->dev, "HD_RECEIVEATDATA_ACK with length 0 ignored\n"); break; } spin_lock_irqsave(&cs->lock, flags); if (ucs->rcvbuf_size) { spin_unlock_irqrestore(&cs->lock, flags); dev_err(cs->dev, "receive AT data overrun, %d bytes lost\n", l); error_reset(cs); //FIXME reschedule break; } if ((ucs->rcvbuf = kmalloc(l, GFP_ATOMIC)) == NULL) { spin_unlock_irqrestore(&cs->lock, flags); dev_err(cs->dev, "out of memory, %d bytes lost\n", l); error_reset(cs); //FIXME reschedule break; } ucs->rcvbuf_size = l; ucs->retry_cmd_in = 0; if ((status = atread_submit(cs, BAS_TIMEOUT)) < 0) { kfree(ucs->rcvbuf); ucs->rcvbuf = NULL; ucs->rcvbuf_size = 0; error_reset(cs); //FIXME reschedule } spin_unlock_irqrestore(&cs->lock, flags); break; case HD_RESET_INTERRUPT_PIPE_ACK: gig_dbg(DEBUG_USBREQ, "HD_RESET_INTERRUPT_PIPE_ACK"); break; case HD_SUSPEND_END: gig_dbg(DEBUG_USBREQ, "HD_SUSPEND_END"); break; default: dev_warn(cs->dev, "unknown Gigaset signal 0x%02x (%u) ignored\n", (int) ucs->int_in_buf[0], l); } check_pending(ucs); resubmit: status = usb_submit_urb(urb, SLAB_ATOMIC); if (unlikely(status)) { dev_err(cs->dev, "could not resubmit interrupt URB: %s\n", get_usb_statmsg(status)); error_reset(cs); } } /* read_ctrl_callback * USB completion handler for control pipe input * called by the USB subsystem in interrupt context * parameter: * urb USB request block * urb->context = inbuf structure for controller state */ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) { struct inbuf_t *inbuf = urb->context; struct cardstate *cs = inbuf->cs; struct bas_cardstate *ucs = cs->hw.bas; int have_data = 0; unsigned numbytes; unsigned long flags; spin_lock_irqsave(&cs->lock, flags); if (unlikely(!atomic_read(&cs->connected))) { warn("%s: disconnected", __func__); spin_unlock_irqrestore(&cs->lock, flags); return; } if (!ucs->rcvbuf_size) { dev_warn(cs->dev, "%s: no receive in progress\n", __func__); spin_unlock_irqrestore(&cs->lock, flags); return; } del_timer(&ucs->timer_cmd_in); switch (urb->status) { case 0: /* normal completion */ numbytes = urb->actual_length; if (unlikely(numbytes == 0)) { dev_warn(cs->dev, "control read: empty block received\n"); goto retry; } if (unlikely(numbytes != ucs->rcvbuf_size)) { dev_warn(cs->dev, "control read: received %d chars, expected %d\n", numbytes, ucs->rcvbuf_size); if (numbytes > ucs->rcvbuf_size) numbytes = ucs->rcvbuf_size; } /* copy received bytes to inbuf */ have_data = gigaset_fill_inbuf(inbuf, ucs->rcvbuf, numbytes); if (unlikely(numbytes < ucs->rcvbuf_size)) { /* incomplete - resubmit for remaining bytes */ ucs->rcvbuf_size -= numbytes; ucs->retry_cmd_in = 0; goto retry; } break; case -ENOENT: /* canceled */ case -ECONNRESET: /* canceled (async) */ case -EINPROGRESS: /* pending */ /* no action necessary */ gig_dbg(DEBUG_USBREQ, "%s: %s", __func__, get_usb_statmsg(urb->status)); break; default: /* severe trouble */ dev_warn(cs->dev, "control read: %s\n", get_usb_statmsg(urb->status)); retry: if (ucs->retry_cmd_in++ < BAS_RETRY) { dev_notice(cs->dev, "control read: retry %d\n", ucs->retry_cmd_in); if (atread_submit(cs, BAS_TIMEOUT) >= 0) { /* resubmitted - bypass regular exit block */ spin_unlock_irqrestore(&cs->lock, flags); return; } } else { dev_err(cs->dev, "control read: giving up after %d tries\n", ucs->retry_cmd_in); } error_reset(cs); } kfree(ucs->rcvbuf); ucs->rcvbuf = NULL; ucs->rcvbuf_size = 0; spin_unlock_irqrestore(&cs->lock, flags); if (have_data) { gig_dbg(DEBUG_INTR, "%s-->BH", __func__); gigaset_schedule_event(cs); } } /* read_iso_callback * USB completion handler for B channel isochronous input * called by the USB subsystem in interrupt context * parameter: * urb USB request block of completed request * urb->context = bc_state structure */ static void read_iso_callback(struct urb *urb, struct pt_regs *regs) { struct bc_state *bcs; struct bas_bc_state *ubc; unsigned long flags; int i, rc; /* status codes not worth bothering the tasklet with */ if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET || urb->status == -EINPROGRESS)) { gig_dbg(DEBUG_ISO, "%s: %s", __func__, get_usb_statmsg(urb->status)); return; } bcs = urb->context; ubc = bcs->hw.bas; spin_lock_irqsave(&ubc->isoinlock, flags); if (likely(ubc->isoindone == NULL)) { /* pass URB to tasklet */ ubc->isoindone = urb; tasklet_schedule(&ubc->rcvd_tasklet); } else { /* tasklet still busy, drop data and resubmit URB */ ubc->loststatus = urb->status; for (i = 0; i < BAS_NUMFRAMES; i++) { ubc->isoinlost += urb->iso_frame_desc[i].actual_length; if (unlikely(urb->iso_frame_desc[i].status != 0 && urb->iso_frame_desc[i].status != -EINPROGRESS)) { ubc->loststatus = urb->iso_frame_desc[i].status; } urb->iso_frame_desc[i].status = 0; urb->iso_frame_desc[i].actual_length = 0; } if (likely(atomic_read(&ubc->running))) { /* urb->dev is clobbered by USB subsystem */ urb->dev = bcs->cs->hw.bas->udev; urb->transfer_flags = URB_ISO_ASAP; urb->number_of_packets = BAS_NUMFRAMES; gig_dbg(DEBUG_ISO, "%s: isoc read overrun/resubmit", __func__); rc = usb_submit_urb(urb, SLAB_ATOMIC); if (unlikely(rc != 0)) { dev_err(bcs->cs->dev, "could not resubmit isochronous read " "URB: %s\n", get_usb_statmsg(rc)); dump_urb(DEBUG_ISO, "isoc read", urb); error_hangup(bcs); } } } spin_unlock_irqrestore(&ubc->isoinlock, flags); } /* write_iso_callback * USB completion handler for B channel isochronous output * called by the USB subsystem in interrupt context * parameter: * urb USB request block of completed request * urb->context = isow_urbctx_t structure */ static void write_iso_callback(struct urb *urb, struct pt_regs *regs) { struct isow_urbctx_t *ucx; struct bas_bc_state *ubc; unsigned long flags; /* status codes not worth bothering the tasklet with */ if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET || urb->status == -EINPROGRESS)) { gig_dbg(DEBUG_ISO, "%s: %s", __func__, get_usb_statmsg(urb->status)); return; } /* pass URB context to tasklet */ ucx = urb->context; ubc = ucx->bcs->hw.bas; spin_lock_irqsave(&ubc->isooutlock, flags); ubc->isooutovfl = ubc->isooutdone; ubc->isooutdone = ucx; spin_unlock_irqrestore(&ubc->isooutlock, flags); tasklet_schedule(&ubc->sent_tasklet); } /* starturbs * prepare and submit USB request blocks for isochronous input and output * argument: * B channel control structure * return value: * 0 on success * < 0 on error (no URBs submitted) */ static int starturbs(struct bc_state *bcs) { struct bas_bc_state *ubc = bcs->hw.bas; struct urb *urb; int j, k; int rc; /* initialize L2 reception */ if (bcs->proto2 == ISDN_PROTO_L2_HDLC) bcs->inputstate |= INS_flag_hunt; /* submit all isochronous input URBs */ atomic_set(&ubc->running, 1); for (k = 0; k < BAS_INURBS; k++) { urb = ubc->isoinurbs[k]; if (!urb) { dev_err(bcs->cs->dev, "isoinurbs[%d]==NULL\n", k); rc = -EFAULT; goto error; } urb->dev = bcs->cs->hw.bas->udev; urb->pipe = usb_rcvisocpipe(urb->dev, 3 + 2 * bcs->channel); urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = ubc->isoinbuf + k * BAS_INBUFSIZE; urb->transfer_buffer_length = BAS_INBUFSIZE; urb->number_of_packets = BAS_NUMFRAMES; urb->interval = BAS_FRAMETIME; urb->complete = read_iso_callback; urb->context = bcs; for (j = 0; j < BAS_NUMFRAMES; j++) { urb->iso_frame_desc[j].offset = j * BAS_MAXFRAME; urb->iso_frame_desc[j].length = BAS_MAXFRAME; urb->iso_frame_desc[j].status = 0; urb->iso_frame_desc[j].actual_length = 0; } dump_urb(DEBUG_ISO, "Initial isoc read", urb); if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) { dev_err(bcs->cs->dev, "could not submit isochronous read URB %d: %s\n", k, get_usb_statmsg(rc)); goto error; } } /* initialize L2 transmission */ gigaset_isowbuf_init(ubc->isooutbuf, PPP_FLAG); /* set up isochronous output URBs for flag idling */ for (k = 0; k < BAS_OUTURBS; ++k) { urb = ubc->isoouturbs[k].urb; if (!urb) { dev_err(bcs->cs->dev, "isoouturbs[%d].urb==NULL\n", k); rc = -EFAULT; goto error; } urb->dev = bcs->cs->hw.bas->udev; urb->pipe = usb_sndisocpipe(urb->dev, 4 + 2 * bcs->channel); urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = ubc->isooutbuf->data; urb->transfer_buffer_length = sizeof(ubc->isooutbuf->data); urb->number_of_packets = BAS_NUMFRAMES; urb->interval = BAS_FRAMETIME; urb->complete = write_iso_callback; urb->context = &ubc->isoouturbs[k]; for (j = 0; j < BAS_NUMFRAMES; ++j) { urb->iso_frame_desc[j].offset = BAS_OUTBUFSIZE; urb->iso_frame_desc[j].length = BAS_NORMFRAME; urb->iso_frame_desc[j].status = 0; urb->iso_frame_desc[j].actual_length = 0; } ubc->isoouturbs[k].limit = -1; } /* submit two URBs, keep third one */ for (k = 0; k < 2; ++k) { dump_urb(DEBUG_ISO, "Initial isoc write", urb); rc = usb_submit_urb(ubc->isoouturbs[k].urb, SLAB_ATOMIC); if (rc != 0) { dev_err(bcs->cs->dev, "could not submit isochronous write URB %d: %s\n", k, get_usb_statmsg(rc)); goto error; } } dump_urb(DEBUG_ISO, "Initial isoc write (free)", urb); ubc->isooutfree = &ubc->isoouturbs[2]; ubc->isooutdone = ubc->isooutovfl = NULL; return 0; error: stopurbs(ubc); return rc; } /* stopurbs * cancel the USB request blocks for isochronous input and output * errors are silently ignored * argument: * B channel control structure */ static void stopurbs(struct bas_bc_state *ubc) { int k, rc; atomic_set(&ubc->running, 0); for (k = 0; k < BAS_INURBS; ++k) { rc = usb_unlink_urb(ubc->isoinurbs[k]); gig_dbg(DEBUG_ISO, "%s: isoc input URB %d unlinked, result = %d", __func__, k, rc); } for (k = 0; k < BAS_OUTURBS; ++k) { rc = usb_unlink_urb(ubc->isoouturbs[k].urb); gig_dbg(DEBUG_ISO, "%s: isoc output URB %d unlinked, result = %d", __func__, k, rc); } } /* Isochronous Write - Bottom Half */ /* =============================== */ /* submit_iso_write_urb * fill and submit the next isochronous write URB * parameters: * bcs B channel state structure * return value: * number of frames submitted in URB * 0 if URB not submitted because no data available (isooutbuf busy) * error code < 0 on error */ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) { struct urb *urb = ucx->urb; struct bas_bc_state *ubc = ucx->bcs->hw.bas; struct usb_iso_packet_descriptor *ifd; int corrbytes, nframe, rc; /* urb->dev is clobbered by USB subsystem */ urb->dev = ucx->bcs->cs->hw.bas->udev; urb->transfer_flags = URB_ISO_ASAP; urb->transfer_buffer = ubc->isooutbuf->data; urb->transfer_buffer_length = sizeof(ubc->isooutbuf->data); for (nframe = 0; nframe < BAS_NUMFRAMES; nframe++) { ifd = &urb->iso_frame_desc[nframe]; /* compute frame length according to flow control */ ifd->length = BAS_NORMFRAME; if ((corrbytes = atomic_read(&ubc->corrbytes)) != 0) { gig_dbg(DEBUG_ISO, "%s: corrbytes=%d", __func__, corrbytes); if (corrbytes > BAS_HIGHFRAME - BAS_NORMFRAME) corrbytes = BAS_HIGHFRAME - BAS_NORMFRAME; else if (corrbytes < BAS_LOWFRAME - BAS_NORMFRAME) corrbytes = BAS_LOWFRAME - BAS_NORMFRAME; ifd->length += corrbytes; atomic_add(-corrbytes, &ubc->corrbytes); } /* retrieve block of data to send */ ifd->offset = gigaset_isowbuf_getbytes(ubc->isooutbuf, ifd->length); if (ifd->offset < 0) { if (ifd->offset == -EBUSY) { gig_dbg(DEBUG_ISO, "%s: buffer busy at frame %d", __func__, nframe); /* tasklet will be restarted from gigaset_send_skb() */ } else { dev_err(ucx->bcs->cs->dev, "%s: buffer error %d at frame %d\n", __func__, ifd->offset, nframe); return ifd->offset; } break; } ucx->limit = atomic_read(&ubc->isooutbuf->nextread); ifd->status = 0; ifd->actual_length = 0; } if ((urb->number_of_packets = nframe) > 0) { if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) { dev_err(ucx->bcs->cs->dev, "could not submit isochronous write URB: %s\n", get_usb_statmsg(rc)); dump_urb(DEBUG_ISO, "isoc write", urb); return rc; } ++ubc->numsub; } return nframe; } /* write_iso_tasklet * tasklet scheduled when an isochronous output URB from the Gigaset device * has completed * parameter: * data B channel state structure */ static void write_iso_tasklet(unsigned long data) { struct bc_state *bcs = (struct bc_state *) data; struct bas_bc_state *ubc = bcs->hw.bas; struct cardstate *cs = bcs->cs; struct isow_urbctx_t *done, *next, *ovfl; struct urb *urb; struct usb_iso_packet_descriptor *ifd; int offset; unsigned long flags; int i; struct sk_buff *skb; int len; /* loop while completed URBs arrive in time */ for (;;) { if (unlikely(!atomic_read(&cs->connected))) { warn("%s: disconnected", __func__); return; } if (unlikely(!(atomic_read(&ubc->running)))) { gig_dbg(DEBUG_ISO, "%s: not running", __func__); return; } /* retrieve completed URBs */ spin_lock_irqsave(&ubc->isooutlock, flags); done = ubc->isooutdone; ubc->isooutdone = NULL; ovfl = ubc->isooutovfl; ubc->isooutovfl = NULL; spin_unlock_irqrestore(&ubc->isooutlock, flags); if (ovfl) { dev_err(cs->dev, "isochronous write buffer underrun\n"); error_hangup(bcs); break; } if (!done) break; /* submit free URB if available */ spin_lock_irqsave(&ubc->isooutlock, flags); next = ubc->isooutfree; ubc->isooutfree = NULL; spin_unlock_irqrestore(&ubc->isooutlock, flags); if (next) { if (submit_iso_write_urb(next) <= 0) { /* could not submit URB, put it back */ spin_lock_irqsave(&ubc->isooutlock, flags); if (ubc->isooutfree == NULL) { ubc->isooutfree = next; next = NULL; } spin_unlock_irqrestore(&ubc->isooutlock, flags); if (next) { /* couldn't put it back */ dev_err(cs->dev, "losing isochronous write URB\n"); error_hangup(bcs); } } } /* process completed URB */ urb = done->urb; switch (urb->status) { case 0: /* normal completion */ break; case -EXDEV: /* inspect individual frames */ /* assumptions (for lack of documentation): * - actual_length bytes of the frame in error are * successfully sent * - all following frames are not sent at all */ gig_dbg(DEBUG_ISO, "%s: URB partially completed", __func__); offset = done->limit; /* just in case */ for (i = 0; i < BAS_NUMFRAMES; i++) { ifd = &urb->iso_frame_desc[i]; if (ifd->status || ifd->actual_length != ifd->length) { dev_warn(cs->dev, "isochronous write: frame %d: %s, " "only %d of %d bytes sent\n", i, get_usb_statmsg(ifd->status), ifd->actual_length, ifd->length); offset = (ifd->offset + ifd->actual_length) % BAS_OUTBUFSIZE; break; } } #ifdef CONFIG_GIGASET_DEBUG /* check assumption on remaining frames */ for (; i < BAS_NUMFRAMES; i++) { ifd = &urb->iso_frame_desc[i]; if (ifd->status != -EINPROGRESS || ifd->actual_length != 0) { dev_warn(cs->dev, "isochronous write: frame %d: %s, " "%d of %d bytes sent\n", i, get_usb_statmsg(ifd->status), ifd->actual_length, ifd->length); offset = (ifd->offset + ifd->actual_length) % BAS_OUTBUFSIZE; break; } } #endif break; case -EPIPE: //FIXME is this the code for "underrun"? dev_err(cs->dev, "isochronous write stalled\n"); error_hangup(bcs); break; default: /* severe trouble */ dev_warn(cs->dev, "isochronous write: %s\n", get_usb_statmsg(urb->status)); } /* mark the write buffer area covered by this URB as free */ if (done->limit >= 0) atomic_set(&ubc->isooutbuf->read, done->limit); /* mark URB as free */ spin_lock_irqsave(&ubc->isooutlock, flags); next = ubc->isooutfree; ubc->isooutfree = done; spin_unlock_irqrestore(&ubc->isooutlock, flags); if (next) { /* only one URB still active - resubmit one */ if (submit_iso_write_urb(next) <= 0) { /* couldn't submit */ error_hangup(bcs); } } } /* process queued SKBs */ while ((skb = skb_dequeue(&bcs->squeue))) { /* copy to output buffer, doing L2 encapsulation */ len = skb->len; if (gigaset_isoc_buildframe(bcs, skb->data, len) == -EAGAIN) { /* insufficient buffer space, push back onto queue */ skb_queue_head(&bcs->squeue, skb); gig_dbg(DEBUG_ISO, "%s: skb requeued, qlen=%d", __func__, skb_queue_len(&bcs->squeue)); break; } skb_pull(skb, len); gigaset_skb_sent(bcs, skb); dev_kfree_skb_any(skb); } } /* Isochronous Read - Bottom Half */ /* ============================== */ /* read_iso_tasklet * tasklet scheduled when an isochronous input URB from the Gigaset device * has completed * parameter: * data B channel state structure */ static void read_iso_tasklet(unsigned long data) { struct bc_state *bcs = (struct bc_state *) data; struct bas_bc_state *ubc = bcs->hw.bas; struct cardstate *cs = bcs->cs; struct urb *urb; char *rcvbuf; unsigned long flags; int totleft, numbytes, offset, frame, rc; /* loop while more completed URBs arrive in the meantime */ for (;;) { if (unlikely(!atomic_read(&cs->connected))) { warn("%s: disconnected", __func__); return; } /* retrieve URB */ spin_lock_irqsave(&ubc->isoinlock, flags); if (!(urb = ubc->isoindone)) { spin_unlock_irqrestore(&ubc->isoinlock, flags); return; } ubc->isoindone = NULL; if (unlikely(ubc->loststatus != -EINPROGRESS)) { dev_warn(cs->dev, "isochronous read overrun, " "dropped URB with status: %s, %d bytes lost\n", get_usb_statmsg(ubc->loststatus), ubc->isoinlost); ubc->loststatus = -EINPROGRESS; } spin_unlock_irqrestore(&ubc->isoinlock, flags); if (unlikely(!(atomic_read(&ubc->running)))) { gig_dbg(DEBUG_ISO, "%s: channel not running, " "dropped URB with status: %s", __func__, get_usb_statmsg(urb->status)); return; } switch (urb->status) { case 0: /* normal completion */ break; case -EXDEV: /* inspect individual frames (we do that anyway) */ gig_dbg(DEBUG_ISO, "%s: URB partially completed", __func__); break; case -ENOENT: case -ECONNRESET: gig_dbg(DEBUG_ISO, "%s: URB canceled", __func__); continue; /* -> skip */ case -EINPROGRESS: /* huh? */ gig_dbg(DEBUG_ISO, "%s: URB still pending", __func__); continue; /* -> skip */ case -EPIPE: dev_err(cs->dev, "isochronous read stalled\n"); error_hangup(bcs); continue; /* -> skip */ default: /* severe trouble */ dev_warn(cs->dev, "isochronous read: %s\n", get_usb_statmsg(urb->status)); goto error; } rcvbuf = urb->transfer_buffer; totleft = urb->actual_length; for (frame = 0; totleft > 0 && frame < BAS_NUMFRAMES; frame++) { if (unlikely(urb->iso_frame_desc[frame].status)) { dev_warn(cs->dev, "isochronous read: frame %d: %s\n", frame, get_usb_statmsg( urb->iso_frame_desc[frame].status)); break; } numbytes = urb->iso_frame_desc[frame].actual_length; if (unlikely(numbytes > BAS_MAXFRAME)) { dev_warn(cs->dev, "isochronous read: frame %d: " "numbytes (%d) > BAS_MAXFRAME\n", frame, numbytes); break; } if (unlikely(numbytes > totleft)) { dev_warn(cs->dev, "isochronous read: frame %d: " "numbytes (%d) > totleft (%d)\n", frame, numbytes, totleft); break; } offset = urb->iso_frame_desc[frame].offset; if (unlikely(offset + numbytes > BAS_INBUFSIZE)) { dev_warn(cs->dev, "isochronous read: frame %d: " "offset (%d) + numbytes (%d) " "> BAS_INBUFSIZE\n", frame, offset, numbytes); break; } gigaset_isoc_receive(rcvbuf + offset, numbytes, bcs); totleft -= numbytes; } if (unlikely(totleft > 0)) dev_warn(cs->dev, "isochronous read: %d data bytes missing\n", totleft); error: /* URB processed, resubmit */ for (frame = 0; frame < BAS_NUMFRAMES; frame++) { urb->iso_frame_desc[frame].status = 0; urb->iso_frame_desc[frame].actual_length = 0; } /* urb->dev is clobbered by USB subsystem */ urb->dev = bcs->cs->hw.bas->udev; urb->transfer_flags = URB_ISO_ASAP; urb->number_of_packets = BAS_NUMFRAMES; if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) { dev_err(cs->dev, "could not resubmit isochronous read URB: %s\n", get_usb_statmsg(rc)); dump_urb(DEBUG_ISO, "resubmit iso read", urb); error_hangup(bcs); } } } /* Channel Operations */ /* ================== */ /* req_timeout * timeout routine for control output request * argument: * B channel control structure */ static void req_timeout(unsigned long data) { struct bc_state *bcs = (struct bc_state *) data; struct bas_cardstate *ucs = bcs->cs->hw.bas; int pending; unsigned long flags; check_pending(ucs); spin_lock_irqsave(&ucs->lock, flags); pending = ucs->pending; ucs->pending = 0; spin_unlock_irqrestore(&ucs->lock, flags); switch (pending) { case 0: /* no pending request */ gig_dbg(DEBUG_USBREQ, "%s: no request pending", __func__); break; case HD_OPEN_ATCHANNEL: dev_err(bcs->cs->dev, "timeout opening AT channel\n"); error_reset(bcs->cs); break; case HD_OPEN_B2CHANNEL: case HD_OPEN_B1CHANNEL: dev_err(bcs->cs->dev, "timeout opening channel %d\n", bcs->channel + 1); error_hangup(bcs); break; case HD_CLOSE_ATCHANNEL: dev_err(bcs->cs->dev, "timeout closing AT channel\n"); break; case HD_CLOSE_B2CHANNEL: case HD_CLOSE_B1CHANNEL: dev_err(bcs->cs->dev, "timeout closing channel %d\n", bcs->channel + 1); break; default: dev_warn(bcs->cs->dev, "request 0x%02x timed out, clearing\n", pending); } } /* write_ctrl_callback * USB completion handler for control pipe output * called by the USB subsystem in interrupt context * parameter: * urb USB request block of completed request * urb->context = hardware specific controller state structure */ static void write_ctrl_callback(struct urb *urb, struct pt_regs *regs) { struct bas_cardstate *ucs = urb->context; unsigned long flags; spin_lock_irqsave(&ucs->lock, flags); if (urb->status && ucs->pending) { dev_err(&ucs->interface->dev, "control request 0x%02x failed: %s\n", ucs->pending, get_usb_statmsg(urb->status)); del_timer(&ucs->timer_ctrl); ucs->pending = 0; } /* individual handling of specific request types */ switch (ucs->pending) { case HD_DEVICE_INIT_ACK: /* no reply expected */ ucs->pending = 0; break; } spin_unlock_irqrestore(&ucs->lock, flags); } /* req_submit * submit a control output request without message buffer to the Gigaset base * and optionally start a timeout * parameters: * bcs B channel control structure * req control request code (HD_*) * val control request parameter value (set to 0 if unused) * timeout timeout in seconds (0: no timeout) * return value: * 0 on success * -EINVAL if a NULL pointer is encountered somewhere * -EBUSY if another request is pending * any URB submission error code */ static int req_submit(struct bc_state *bcs, int req, int val, int timeout) { struct bas_cardstate *ucs = bcs->cs->hw.bas; int ret; unsigned long flags; gig_dbg(DEBUG_USBREQ, "-------> 0x%02x (%d)", req, val); spin_lock_irqsave(&ucs->lock, flags); if (ucs->pending) { spin_unlock_irqrestore(&ucs->lock, flags); dev_err(bcs->cs->dev, "submission of request 0x%02x failed: " "request 0x%02x still pending\n", req, ucs->pending); return -EBUSY; } if (ucs->urb_ctrl->status == -EINPROGRESS) { spin_unlock_irqrestore(&ucs->lock, flags); dev_err(bcs->cs->dev, "could not submit request 0x%02x: URB busy\n", req); return -EBUSY; } ucs->dr_ctrl.bRequestType = OUT_VENDOR_REQ; ucs->dr_ctrl.bRequest = req; ucs->dr_ctrl.wValue = cpu_to_le16(val); ucs->dr_ctrl.wIndex = 0; ucs->dr_ctrl.wLength = 0; usb_fill_control_urb(ucs->urb_ctrl, ucs->udev, usb_sndctrlpipe(ucs->udev, 0), (unsigned char*) &ucs->dr_ctrl, NULL, 0, write_ctrl_callback, ucs); if ((ret = usb_submit_urb(ucs->urb_ctrl, SLAB_ATOMIC)) != 0) { dev_err(bcs->cs->dev, "could not submit request 0x%02x: %s\n", req, get_usb_statmsg(ret)); spin_unlock_irqrestore(&ucs->lock, flags); return ret; } ucs->pending = req; if (timeout > 0) { gig_dbg(DEBUG_USBREQ, "setting timeout of %d/10 secs", timeout); ucs->timer_ctrl.expires = jiffies + timeout * HZ / 10; ucs->timer_ctrl.data = (unsigned long) bcs; ucs->timer_ctrl.function = req_timeout; add_timer(&ucs->timer_ctrl); } spin_unlock_irqrestore(&ucs->lock, flags); return 0; } /* gigaset_init_bchannel * called by common.c to connect a B channel * initialize isochronous I/O and tell the Gigaset base to open the channel * argument: * B channel control structure * return value: * 0 on success, error code < 0 on error */ static int gigaset_init_bchannel(struct bc_state *bcs) { int req, ret; if ((ret = starturbs(bcs)) < 0) { dev_err(bcs->cs->dev, "could not start isochronous I/O for channel %d\n", bcs->channel + 1); error_hangup(bcs); return ret; } req = bcs->channel ? HD_OPEN_B2CHANNEL : HD_OPEN_B1CHANNEL; if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) { dev_err(bcs->cs->dev, "could not open channel %d: %s\n", bcs->channel + 1, get_usb_statmsg(ret)); stopurbs(bcs->hw.bas); error_hangup(bcs); } return ret; } /* gigaset_close_bchannel * called by common.c to disconnect a B channel * tell the Gigaset base to close the channel * stopping isochronous I/O and LL notification will be done when the * acknowledgement for the close arrives * argument: * B channel control structure * return value: * 0 on success, error code < 0 on error */ static int gigaset_close_bchannel(struct bc_state *bcs) { int req, ret; if (!(atomic_read(&bcs->cs->hw.bas->basstate) & (bcs->channel ? BS_B2OPEN : BS_B1OPEN))) { /* channel not running: just signal common.c */ gigaset_bchannel_down(bcs); return 0; } req = bcs->channel ? HD_CLOSE_B2CHANNEL : HD_CLOSE_B1CHANNEL; if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) dev_err(bcs->cs->dev, "could not submit HD_CLOSE_BxCHANNEL request: %s\n", get_usb_statmsg(ret)); return ret; } /* Device Operations */ /* ================= */ /* complete_cb * unqueue first command buffer from queue, waking any sleepers * must be called with cs->cmdlock held * parameter: * cs controller state structure */ static void complete_cb(struct cardstate *cs) { struct cmdbuf_t *cb = cs->cmdbuf; /* unqueue completed buffer */ cs->cmdbytes -= cs->curlen; gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "write_command: sent %u bytes, %u left", cs->curlen, cs->cmdbytes); if ((cs->cmdbuf = cb->next) != NULL) { cs->cmdbuf->prev = NULL; cs->curlen = cs->cmdbuf->len; } else { cs->lastcmdbuf = NULL; cs->curlen = 0; } if (cb->wake_tasklet) tasklet_schedule(cb->wake_tasklet); kfree(cb); } static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len); /* write_command_callback * USB completion handler for AT command transmission * called by the USB subsystem in interrupt context * parameter: * urb USB request block of completed request * urb->context = controller state structure */ static void write_command_callback(struct urb *urb, struct pt_regs *regs) { struct cardstate *cs = urb->context; struct bas_cardstate *ucs = cs->hw.bas; unsigned long flags; /* check status */ switch (urb->status) { case 0: /* normal completion */ break; case -ENOENT: /* canceled */ case -ECONNRESET: /* canceled (async) */ case -EINPROGRESS: /* pending */ /* ignore silently */ gig_dbg(DEBUG_USBREQ, "%s: %s", __func__, get_usb_statmsg(urb->status)); return; default: /* any failure */ if (++ucs->retry_cmd_out > BAS_RETRY) { dev_warn(cs->dev, "command write: %s, "