···11+Device-mapper snapshot support22+==============================33+44+Device-mapper allows you, without massive data copying:55+66+*) To create snapshots of any block device i.e. mountable, saved states of77+the block device which are also writable without interfering with the88+original content;99+*) To create device "forks", i.e. multiple different versions of the1010+same data stream.1111+1212+1313+In both cases, dm copies only the chunks of data that get changed and1414+uses a separate copy-on-write (COW) block device for storage.1515+1616+1717+There are two dm targets available: snapshot and snapshot-origin.1818+1919+*) snapshot-origin <origin>2020+2121+which will normally have one or more snapshots based on it.2222+You must create the snapshot-origin device before you can create snapshots.2323+Reads will be mapped directly to the backing device. For each write, the2424+original data will be saved in the <COW device> of each snapshot to keep2525+its visible content unchanged, at least until the <COW device> fills up.2626+2727+2828+*) snapshot <origin> <COW device> <persistent?> <chunksize>2929+3030+A snapshot is created of the <origin> block device. Changed chunks of3131+<chunksize> sectors will be stored on the <COW device>. Writes will3232+only go to the <COW device>. Reads will come from the <COW device> or3333+from <origin> for unchanged data. <COW device> will often be3434+smaller than the origin and if it fills up the snapshot will become3535+useless and be disabled, returning errors. So it is important to monitor3636+the amount of free space and expand the <COW device> before it fills up.3737+3838+<persistent?> is P (Persistent) or N (Not persistent - will not survive3939+after reboot).4040+4141+4242+How this is used by LVM24343+========================4444+When you create the first LVM2 snapshot of a volume, four dm devices are used:4545+4646+1) a device containing the original mapping table of the source volume;4747+2) a device used as the <COW device>;4848+3) a "snapshot" device, combining #1 and #2, which is the visible snapshot4949+ volume;5050+4) the "original" volume (which uses the device number used by the original5151+ source volume), whose table is replaced by a "snapshot-origin" mapping5252+ from device #1.5353+5454+A fixed naming scheme is used, so with the following commands:5555+5656+lvcreate -L 1G -n base volumeGroup5757+lvcreate -L 100M --snapshot -n snap volumeGroup/base5858+5959+we'll have this situation (with volumes in above order):6060+6161+# dmsetup table|grep volumeGroup6262+6363+volumeGroup-base-real: 0 2097152 linear 8:19 3846464+volumeGroup-snap-cow: 0 204800 linear 8:19 20975366565+volumeGroup-snap: 0 2097152 snapshot 254:11 254:12 P 166666+volumeGroup-base: 0 2097152 snapshot-origin 254:116767+6868+# ls -lL /dev/mapper/volumeGroup-*6969+brw------- 1 root root 254, 11 29 ago 18:15 /dev/mapper/volumeGroup-base-real7070+brw------- 1 root root 254, 12 29 ago 18:15 /dev/mapper/volumeGroup-snap-cow7171+brw------- 1 root root 254, 13 29 ago 18:15 /dev/mapper/volumeGroup-snap7272+brw------- 1 root root 254, 10 29 ago 18:14 /dev/mapper/volumeGroup-base7373+
+2-2
Documentation/sparse.txt
···5151Where to get sparse5252~~~~~~~~~~~~~~~~~~~53535454-With BK, you can just get it from5454+With git, you can just get it from55555656- bk://sparse.bkbits.net/sparse5656+ rsync://rsync.kernel.org/pub/scm/devel/sparse/sparse.git57575858and DaveJ has tar-balls at5959
+31-43
Documentation/usb/URB.txt
···11Revised: 2000-Dec-05.22Again: 2002-Jul-0633+Again: 2005-Sep-193445 NOTE:56···1918 and deliver the data and status back. 20192120- Execution of an URB is inherently an asynchronous operation, i.e. the 2222- usb_submit_urb(urb) call returns immediately after it has successfully queued 2323- the requested action. 2121+ usb_submit_urb(urb) call returns immediately after it has successfully2222+ queued the requested action.24232524- Transfers for one URB can be canceled with usb_unlink_urb(urb) at any time. 2625···95949695 void usb_free_urb(struct urb *urb)97969898-You may not free an urb that you've submitted, but which hasn't yet been9999-returned to you in a completion callback.9797+You may free an urb that you've submitted, but which hasn't yet been9898+returned to you in a completion callback. It will automatically be9999+deallocated when it is no longer in use.1001001011011021021.4. What has to be filled in?···1471451481461.6. How to cancel an already running URB?149147150150-For an URB which you've submitted, but which hasn't been returned to151151-your driver by the host controller, call148148+There are two ways to cancel an URB you've submitted but which hasn't149149+been returned to your driver yet. For an asynchronous cancel, call152150153151 int usb_unlink_urb(struct urb *urb)154152155153It removes the urb from the internal list and frees all allocated156156-HW descriptors. The status is changed to reflect unlinking. After 157157-usb_unlink_urb() returns with that status code, you can free the URB158158-with usb_free_urb().154154+HW descriptors. The status is changed to reflect unlinking. Note155155+that the URB will not normally have finished when usb_unlink_urb()156156+returns; you must still wait for the completion handler to be called.159157160160-There is also an asynchronous unlink mode. To use this, set the161161-the URB_ASYNC_UNLINK flag in urb->transfer flags before calling162162-usb_unlink_urb(). When using async unlinking, the URB will not163163-normally be unlinked when usb_unlink_urb() returns. Instead, wait164164-for the completion handler to be called.158158+To cancel an URB synchronously, call159159+160160+ void usb_kill_urb(struct urb *urb)161161+162162+It does everything usb_unlink_urb does, and in addition it waits163163+until after the URB has been returned and the completion handler164164+has finished. It also marks the URB as temporarily unusable, so165165+that if the completion handler or anyone else tries to resubmit it166166+they will get a -EPERM error. Thus you can be sure that when167167+usb_kill_urb() returns, the URB is totally idle.1651681661691671701.7. What about the completion handler?168171169172The handler is of the following type:170173171171- typedef void (*usb_complete_t)(struct urb *);174174+ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *)172175173173-i.e. it gets just the URB that caused the completion call.176176+I.e., it gets the URB that caused the completion call, plus the177177+register values at the time of the corresponding interrupt (if any).174178In the completion handler, you should have a look at urb->status to175179detect any USB errors. Since the context parameter is included in the URB,176180you can pass information to the completion handler. ···184176Note that even when an error (or unlink) is reported, data may have been185177transferred. That's because USB transfers are packetized; it might take186178sixteen packets to transfer your 1KByte buffer, and ten of them might187187-have transferred succesfully before the completion is called.179179+have transferred succesfully before the completion was called.188180189181190182NOTE: ***** WARNING *****191191-Don't use urb->dev field in your completion handler; it's cleared192192-as part of giving urbs back to drivers. (Addressing an issue with193193-ownership of periodic URBs, which was otherwise ambiguous.) Instead,194194-use urb->context to hold all the data your driver needs.195195-196196-NOTE: ***** WARNING *****197197-Also, NEVER SLEEP IN A COMPLETION HANDLER. These are normally called183183+NEVER SLEEP IN A COMPLETION HANDLER. These are normally called198184during hardware interrupt processing. If you can, defer substantial199185work to a tasklet (bottom half) to keep system latencies low. You'll200186probably need to use spinlocks to protect data structures you manipulate···231229Interrupt transfers, like isochronous transfers, are periodic, and happen232230in intervals that are powers of two (1, 2, 4 etc) units. Units are frames233231for full and low speed devices, and microframes for high speed ones.234234-235235-Currently, after you submit one interrupt URB, that urb is owned by the236236-host controller driver until you cancel it with usb_unlink_urb(). You237237-may unlink interrupt urbs in their completion handlers, if you need to.238238-239239-After a transfer completion is called, the URB is automagically resubmitted.240240-THIS BEHAVIOR IS EXPECTED TO BE REMOVED!!241241-242242-Interrupt transfers may only send (or receive) the "maxpacket" value for243243-the given interrupt endpoint; if you need more data, you will need to244244-copy that data out of (or into) another buffer. Similarly, you can't245245-queue interrupt transfers.246246-THESE RESTRICTIONS ARE EXPECTED TO BE REMOVED!!247247-248248-Note that this automagic resubmission model does make it awkward to use249249-interrupt OUT transfers. The portable solution involves unlinking those250250-OUT urbs after the data is transferred, and perhaps submitting a final251251-URB for a short packet.252252-253232The usb_submit_urb() call modifies urb->interval to the implemented interval254233value that is less than or equal to the requested interval value.234234+235235+In Linux 2.6, unlike earlier versions, interrupt URBs are not automagically236236+restarted when they complete. They end when the completion handler is237237+called, just like other URBs. If you want an interrupt URB to be restarted,238238+your completion handler must resubmit it.
+18-2
MAINTAINERS
···10631063S: Maintained1064106410651065I2C SUBSYSTEM10661066-P: Greg Kroah-Hartman10671067-M: greg@kroah.com10681066P: Jean Delvare10691067M: khali@linux-fr.org10701068L: lm-sensors@lm-sensors.org···14001402W: http://www.xmission.com/~ebiederm/files/kexec/14011403L: linux-kernel@vger.kernel.org14021404L: fastboot@osdl.org14051405+S: Maintained14061406+14071407+KPROBES14081408+P: Prasanna S Panchamukhi14091409+M: prasanna@in.ibm.com14101410+P: Ananth N Mavinakayanahalli14111411+M: ananth@in.ibm.com14121412+P: Anil S Keshavamurthy14131413+M: anil.s.keshavamurthy@intel.com14141414+P: David S. Miller14151415+M: davem@davemloft.net14161416+L: linux-kernel@vger.kernel.org14031417S: Maintained1404141814051419LANMEDIA WAN CARD DRIVER···22742264P: Kristen Carlson Accardi22752265M: kristen.c.accardi@intel.com22762266L: pcihpd-discuss@lists.sourceforge.net22672267+S: Maintained22682268+22692269+SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS22702270+P: Stephen Hemminger22712271+M: shemminger@osdl.org22722272+L: netdev@vger.kernel.org22772273S: Maintained2278227422792275SPARC (sparc32):
···149149 "make gconfig" X windows (Gtk) based configuration tool.150150 "make oldconfig" Default all questions based on the contents of151151 your existing ./.config file.152152+ "make silentoldconfig"153153+ Like above, but avoids cluttering the screen154154+ with questions already answered.152155153156 NOTES on "make config":154157 - having unnecessary drivers will make the kernel bigger, and can···171168 break bad code to find kernel problems (kmalloc()). Thus you172169 should probably answer 'n' to the questions for173170 "development", "experimental", or "debugging" features.174174-175175- - Check the top Makefile for further site-dependent configuration176176- (default SVGA mode etc). 177171178172COMPILING the kernel:179173···199199 are installing a new kernel with the same version number as your200200 working kernel, make a backup of your modules directory before you201201 do a "make modules_install".202202+ Alternatively, before compiling, use the kernel config option203203+ "LOCALVERSION" to append a unique suffix to the regular kernel version.204204+ LOCALVERSION can be set in the "General Setup" menu.202205203206 - In order to boot your new kernel, you'll need to copy the kernel204207 image (e.g. .../linux/arch/i386/boot/bzImage after compilation)
+4
arch/alpha/kernel/process.c
···127127 /* If booted from SRM, reset some of the original environment. */128128 if (alpha_using_srm) {129129#ifdef CONFIG_DUMMY_CONSOLE130130+ /* If we've gotten here after SysRq-b, leave interrupt131131+ context before taking over the console. */132132+ if (in_interrupt())133133+ irq_exit();130134 /* This has the effect of resetting the VGA video origin. */131135 take_over_console(&dummy_con, 0, MAX_NR_CONSOLES-1, 1);132136#endif
+23-18
arch/alpha/kernel/sys_dp264.c
···395395 */396396397397static int __init398398+isa_irq_fixup(struct pci_dev *dev, int irq)399399+{400400+ u8 irq8;401401+402402+ if (irq > 0)403403+ return irq;404404+405405+ /* This interrupt is routed via ISA bridge, so we'll406406+ just have to trust whatever value the console might407407+ have assigned. */408408+ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8);409409+410410+ return irq8 & 0xf;411411+}412412+413413+static int __init398414dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin)399415{400416 static char irq_tab[6][5] __initdata = {···423407 { 16+ 3, 16+ 3, 16+ 2, 16+ 1, 16+ 0} /* IdSel 10 slot 3 */424408 };425409 const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5;426426-427410 struct pci_controller *hose = dev->sysdata;428411 int irq = COMMON_TABLE_LOOKUP;429412430430- if (irq > 0) {413413+ if (irq > 0)431414 irq += 16 * hose->index;432432- } else {433433- /* ??? The Contaq IDE controller on the ISA bridge uses434434- "legacy" interrupts 14 and 15. I don't know if anything435435- can wind up at the same slot+pin on hose1, so we'll436436- just have to trust whatever value the console might437437- have assigned. */438415439439- u8 irq8;440440- pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8);441441- irq = irq8;442442- }443443-444444- return irq;416416+ return isa_irq_fixup(dev, irq);445417}446418447419static int __init···457453 { 24, 24, 25, 26, 27} /* IdSel 15 slot 5 PCI2*/458454 };459455 const long min_idsel = 3, max_idsel = 15, irqs_per_slot = 5;460460- return COMMON_TABLE_LOOKUP;456456+457457+ return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP);461458}462459463460static u8 __init···512507 { 47, 47, 46, 45, 44}, /* IdSel 17 slot 3 */513508 };514509 const long min_idsel = 7, max_idsel = 17, irqs_per_slot = 5;515515- return COMMON_TABLE_LOOKUP;510510+511511+ return isa_irq_fixup(dev, COMMON_TABLE_LOOKUP);516512}517513518514static int __init···530524 { -1, -1, -1, -1, -1} /* IdSel 7 ISA Bridge */531525 };532526 const long min_idsel = 1, max_idsel = 7, irqs_per_slot = 5;533533-534527 struct pci_controller *hose = dev->sysdata;535528 int irq = COMMON_TABLE_LOOKUP;536529537530 if (irq > 0)538531 irq += 16 * hose->index;539532540540- return irq;533533+ return isa_irq_fixup(dev, irq);541534}542535543536static void __init
···77 * Copy data from IO memory space to "real" memory space.88 * This needs to be optimized.99 */1010-void _memcpy_fromio(void *to, void __iomem *from, size_t count)1010+void _memcpy_fromio(void *to, const volatile void __iomem *from, size_t count)1111{1212 unsigned char *t = to;1313 while (count) {···2222 * Copy data from "real" memory space to IO memory space.2323 * This needs to be optimized.2424 */2525-void _memcpy_toio(void __iomem *to, const void *from, size_t count)2525+void _memcpy_toio(volatile void __iomem *to, const void *from, size_t count)2626{2727 const unsigned char *f = from;2828 while (count) {···3737 * "memset" on IO memory space.3838 * This needs to be optimized.3939 */4040-void _memset_io(void __iomem *dst, int c, size_t count)4040+void _memset_io(volatile void __iomem *dst, int c, size_t count)4141{4242 while (count) {4343 count--;
+1-1
arch/arm/kernel/semaphore.c
···178178 * registers (r0 to r3 and lr), but not ip, as we use it as a return179179 * value in some cases..180180 */181181-asm(" .section .sched.text,\"ax\" \n\181181+asm(" .section .sched.text,\"ax\",%progbits \n\182182 .align 5 \n\183183 .globl __down_failed \n\184184__down_failed: \n\
+3
arch/arm/kernel/traps.c
···624624 printk(" - extra data = %p", data);625625 printk("\n");626626 *(int *)0 = 0;627627+628628+ /* Avoid "noreturn function does return" */629629+ for (;;);627630}628631EXPORT_SYMBOL(__bug);629632
···9797 .devices_count = ARRAY_SIZE(n30_devices)9898};9999100100-void __init n30_map_io(void)100100+static void __init n30_map_io(void)101101{102102 s3c24xx_init_io(n30_iodesc, ARRAY_SIZE(n30_iodesc));103103 s3c24xx_init_clocks(0);···105105 s3c24xx_set_board(&n30_board);106106}107107108108-void __init n30_init_irq(void)108108+static void __init n30_init_irq(void)109109{110110 s3c24xx_init_irq();111111}112112113113/* GPB3 is the line that controls the pull-up for the USB D+ line */114114115115-void __init n30_init(void)115115+static void __init n30_init(void)116116{117117 s3c_device_i2c.dev.platform_data = &n30_i2ccfg;118118
···233233 if (in_interrupt() || !mm)234234 goto no_context;235235236236- down_read(&mm->mmap_sem);236236+ /*237237+ * As per x86, we may deadlock here. However, since the kernel only238238+ * validly references user space from well defined areas of the code,239239+ * we can bug out early if this is from code which shouldn't.240240+ */241241+ if (!down_read_trylock(&mm->mmap_sem)) {242242+ if (!user_mode(regs) && !search_exception_tables(regs->ARM_pc))243243+ goto no_context;244244+ down_read(&mm->mmap_sem);245245+ }246246+237247 fault = __do_page_fault(mm, addr, fsr, tsk);238248 up_read(&mm->mmap_sem);239249
···222222 * See linux/include/asm-arm/procinfo.h for a definition of this structure.223223 */224224225225- .section ".proc.info", #alloc, #execinstr225225+ .section ".proc.info.init", #alloc, #execinstr226226227227 .type __arm710_proc_info, #object228228__arm710_proc_info:
···281281 tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT;282282283283 /* Test if we are going over 2GB of DMA space */284284- if (phb->dma_window_base_cur + phb->dma_window_size > (1L << 31))284284+ if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) {285285+ udbg_printf("PCI_DMA: Unexpected number of IOAs under this PHB.\n");285286 panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); 287287+ }286288287289 phb->dma_window_base_cur += phb->dma_window_size;288290···328326329327static void iommu_bus_setup_pSeries(struct pci_bus *bus)330328{331331- struct device_node *dn, *pdn;332332- struct pci_dn *pci;329329+ struct device_node *dn;333330 struct iommu_table *tbl;331331+ struct device_node *isa_dn, *isa_dn_orig;332332+ struct device_node *tmp;333333+ struct pci_dn *pci;334334+ int children;334335335336 DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);336337337337- /* For each (root) bus, we carve up the available DMA space in 256MB338338- * pieces. Since each piece is used by one (sub) bus/device, that would339339- * give a maximum of 7 devices per PHB. In most cases, this is plenty.338338+ dn = pci_bus_to_OF_node(bus);339339+ pci = PCI_DN(dn);340340+341341+ if (bus->self) {342342+ /* This is not a root bus, any setup will be done for the343343+ * device-side of the bridge in iommu_dev_setup_pSeries().344344+ */345345+ return;346346+ }347347+348348+ /* Check if the ISA bus on the system is under349349+ * this PHB.350350+ */351351+ isa_dn = isa_dn_orig = of_find_node_by_type(NULL, "isa");352352+353353+ while (isa_dn && isa_dn != dn)354354+ isa_dn = isa_dn->parent;355355+356356+ if (isa_dn_orig)357357+ of_node_put(isa_dn_orig);358358+359359+ /* Count number of direct PCI children of the PHB.360360+ * All PCI device nodes have class-code property, so it's361361+ * an easy way to find them.362362+ */363363+ for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling)364364+ if (get_property(tmp, "class-code", NULL))365365+ children++;366366+367367+ DBG("Children: %d\n", children);368368+369369+ /* Calculate amount of DMA window per slot. Each window must be370370+ * a power of two (due to pci_alloc_consistent requirements).340371 *341341- * The exception is on Python PHBs (pre-POWER4). Here we don't have EADS342342- * bridges below the PHB to allocate the sectioned tables to, so instead343343- * we allocate a 1GB table at the PHB level.372372+ * Keep 256MB aside for PHBs with ISA.344373 */345374346346- dn = pci_bus_to_OF_node(bus);347347- pci = dn->data;375375+ if (!isa_dn) {376376+ /* No ISA/IDE - just set window size and return */377377+ pci->phb->dma_window_size = 0x80000000ul; /* To be divided */348378349349- if (!bus->self) {350350- /* Root bus */351351- if (is_python(dn)) {352352- unsigned int *iohole;379379+ while (pci->phb->dma_window_size * children > 0x80000000ul)380380+ pci->phb->dma_window_size >>= 1;381381+ DBG("No ISA/IDE, window size is 0x%lx\n",382382+ pci->phb->dma_window_size);383383+ pci->phb->dma_window_base_cur = 0;353384354354- DBG("Python root bus %s\n", bus->name);355355-356356- iohole = (unsigned int *)get_property(dn, "io-hole", 0);357357-358358- if (iohole) {359359- /* On first bus we need to leave room for the360360- * ISA address space. Just skip the first 256MB361361- * alltogether. This leaves 768MB for the window.362362- */363363- DBG("PHB has io-hole, reserving 256MB\n");364364- pci->phb->dma_window_size = 3 << 28;365365- pci->phb->dma_window_base_cur = 1 << 28;366366- } else {367367- /* 1GB window by default */368368- pci->phb->dma_window_size = 1 << 30;369369- pci->phb->dma_window_base_cur = 0;370370- }371371-372372- tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);373373-374374- iommu_table_setparms(pci->phb, dn, tbl);375375- pci->iommu_table = iommu_init_table(tbl);376376- } else {377377- /* Do a 128MB table at root. This is used for the IDE378378- * controller on some SMP-mode POWER4 machines. It379379- * doesn't hurt to allocate it on other machines380380- * -- it'll just be unused since new tables are381381- * allocated on the EADS level.382382- *383383- * Allocate at offset 128MB to avoid having to deal384384- * with ISA holes; 128MB table for IDE is plenty.385385- */386386- pci->phb->dma_window_size = 1 << 27;387387- pci->phb->dma_window_base_cur = 1 << 27;388388-389389- tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);390390-391391- iommu_table_setparms(pci->phb, dn, tbl);392392- pci->iommu_table = iommu_init_table(tbl);393393-394394- /* All child buses have 256MB tables */395395- pci->phb->dma_window_size = 1 << 28;396396- }397397- } else {398398- pdn = pci_bus_to_OF_node(bus->parent);399399-400400- if (!bus->parent->self && !is_python(pdn)) {401401- struct iommu_table *tbl;402402- /* First child and not python means this is the EADS403403- * level. Allocate new table for this slot with 256MB404404- * window.405405- */406406-407407- tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);408408-409409- iommu_table_setparms(pci->phb, dn, tbl);410410-411411- pci->iommu_table = iommu_init_table(tbl);412412- } else {413413- /* Lower than first child or under python, use parent table */414414- pci->iommu_table = PCI_DN(pdn)->iommu_table;415415- }385385+ return;416386 }387387+388388+ /* If we have ISA, then we probably have an IDE389389+ * controller too. Allocate a 128MB table but390390+ * skip the first 128MB to avoid stepping on ISA391391+ * space.392392+ */393393+ pci->phb->dma_window_size = 0x8000000ul;394394+ pci->phb->dma_window_base_cur = 0x8000000ul;395395+396396+ tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);397397+398398+ iommu_table_setparms(pci->phb, dn, tbl);399399+ pci->iommu_table = iommu_init_table(tbl);400400+401401+ /* Divide the rest (1.75GB) among the children */402402+ pci->phb->dma_window_size = 0x80000000ul;403403+ while (pci->phb->dma_window_size * children > 0x70000000ul)404404+ pci->phb->dma_window_size >>= 1;405405+406406+ DBG("ISA/IDE, window size is 0x%lx\n", pci->phb->dma_window_size);407407+417408}418409419410···457462static void iommu_dev_setup_pSeries(struct pci_dev *dev)458463{459464 struct device_node *dn, *mydn;465465+ struct iommu_table *tbl;460466461461- DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, dev->pretty_name);462462- /* Now copy the iommu_table ptr from the bus device down to the463463- * pci device_node. This means get_iommu_table() won't need to search464464- * up the device tree to find it.465465- */467467+ DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, pci_name(dev));468468+466469 mydn = dn = pci_device_to_OF_node(dev);470470+471471+ /* If we're the direct child of a root bus, then we need to allocate472472+ * an iommu table ourselves. The bus setup code should have setup473473+ * the window sizes already.474474+ */475475+ if (!dev->bus->self) {476476+ DBG(" --> first child, no bridge. Allocating iommu table.\n");477477+ tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL);478478+ iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl);479479+ PCI_DN(mydn)->iommu_table = iommu_init_table(tbl);480480+481481+ return;482482+ }483483+484484+ /* If this device is further down the bus tree, search upwards until485485+ * an already allocated iommu table is found and use that.486486+ */467487468488 while (dn && dn->data && PCI_DN(dn)->iommu_table == NULL)469489 dn = dn->parent;···486476 if (dn && dn->data) {487477 PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table;488478 } else {489489- DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, dev->pretty_name);479479+ DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, pci_name(dev));490480 }491481}492482···520510 int *dma_window = NULL;521511 struct pci_dn *pci;522512523523- DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, dev->pretty_name);513513+ DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev));524514525515 /* dev setup for LPAR is a little tricky, since the device tree might526516 * contain the dma-window properties per-device and not neccesarily···542532 * slots on POWER4 machines.543533 */544534 if (dma_window == NULL || pdn->parent == NULL) {545545- /* Fall back to regular (non-LPAR) dev setup */546546- DBG("No dma window for device, falling back to regular setup\n");547547- iommu_dev_setup_pSeries(dev);535535+ DBG("No dma window for device, linking to parent\n");536536+ PCI_DN(dn)->iommu_table = PCI_DN(pdn)->iommu_table;548537 return;549538 } else {550539 DBG("Found DMA window, allocating table\n");
···219219220220 case PTRACE_SET_DEBUGREG:221221 ret = ptrace_set_debugreg(child, addr, data);222222+ break;222223223224 case PTRACE_DETACH:224225 ret = ptrace_detach(child, data);
+2-3
arch/ppc64/mm/hash_native.c
···342342 hpte_t *hptep;343343 unsigned long hpte_v;344344 struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);345345-346346- /* XXX fix for large ptes */347347- unsigned long large = 0;345345+ unsigned long large;348346349347 local_irq_save(flags);350348351349 j = 0;352350 for (i = 0; i < number; i++) {353351 va = batch->vaddr[j];352352+ large = pte_huge(batch->pte[i]);354353 if (large)355354 vpn = va >> HPAGE_SHIFT;356355 else
···184184 unsigned long *saddr, int is_signed, int asi);185185186186extern void __do_int_store(unsigned long *dst_addr, int size,187187- unsigned long *src_val, int asi);187187+ unsigned long src_val, int asi);188188189189static inline void do_int_store(int reg_num, int size, unsigned long *dst_addr,190190- struct pt_regs *regs, int asi)190190+ struct pt_regs *regs, int asi, int orig_asi)191191{192192 unsigned long zero = 0;193193- unsigned long *src_val = &zero;193193+ unsigned long *src_val_p = &zero;194194+ unsigned long src_val;194195195196 if (size == 16) {196197 size = 8;···199198 (unsigned)fetch_reg(reg_num, regs) : 0)) << 32) |200199 (unsigned)fetch_reg(reg_num + 1, regs);201200 } else if (reg_num) {202202- src_val = fetch_reg_addr(reg_num, regs);201201+ src_val_p = fetch_reg_addr(reg_num, regs);202202+ }203203+ src_val = *src_val_p;204204+ if (unlikely(asi != orig_asi)) {205205+ switch (size) {206206+ case 2:207207+ src_val = swab16(src_val);208208+ break;209209+ case 4:210210+ src_val = swab32(src_val);211211+ break;212212+ case 8:213213+ src_val = swab64(src_val);214214+ break;215215+ case 16:216216+ default:217217+ BUG();218218+ break;219219+ };203220 }204221 __do_int_store(dst_addr, size, src_val, asi);205222}···295276 kernel_mna_trap_fault();296277 } else {297278 unsigned long addr;279279+ int orig_asi, asi;298280299281 addr = compute_effective_address(regs, insn,300282 ((insn >> 25) & 0x1f));···305285 regs->tpc, dirstrings[dir], addr, size,306286 regs->u_regs[UREG_RETPC]);307287#endif288288+ orig_asi = asi = decode_asi(insn, regs);289289+ switch (asi) {290290+ case ASI_NL:291291+ case ASI_AIUPL:292292+ case ASI_AIUSL:293293+ case ASI_PL:294294+ case ASI_SL:295295+ case ASI_PNFL:296296+ case ASI_SNFL:297297+ asi &= ~0x08;298298+ break;299299+ };308300 switch (dir) {309301 case load:310302 do_int_load(fetch_reg_addr(((insn>>25)&0x1f), regs),311303 size, (unsigned long *) addr,312312- decode_signedness(insn),313313- decode_asi(insn, regs));304304+ decode_signedness(insn), asi);305305+ if (unlikely(asi != orig_asi)) {306306+ unsigned long val_in = *(unsigned long *) addr;307307+ switch (size) {308308+ case 2:309309+ val_in = swab16(val_in);310310+ break;311311+ case 4:312312+ val_in = swab32(val_in);313313+ break;314314+ case 8:315315+ val_in = swab64(val_in);316316+ break;317317+ case 16:318318+ default:319319+ BUG();320320+ break;321321+ };322322+ *(unsigned long *) addr = val_in;323323+ }314324 break;315325316326 case store:317327 do_int_store(((insn>>25)&0x1f), size,318328 (unsigned long *) addr, regs,319319- decode_asi(insn, regs));329329+ asi, orig_asi);320330 break;321331322332 default:
+5-1
arch/um/Makefile
···53535454# -Dvmap=kernel_vmap affects everything, and prevents anything from5555# referencing the libpcap.o symbol so named.5656+#5757+# Same things for in6addr_loopback - found in libc.56585759CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \5858- $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap6060+ $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \6161+ -Din6addr_loopback=kernel_in6addr_loopback6262+5963AFLAGS += $(ARCH_INCLUDE)60646165USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
+43-17
arch/um/drivers/chan_kern.c
···1919#include "line.h"2020#include "os.h"21212222-#ifdef CONFIG_NOCONFIG_CHAN2222+/* XXX: could well be moved to somewhere else, if needed. */2323+static int my_printf(const char * fmt, ...)2424+ __attribute__ ((format (printf, 1, 2)));23252424-/* The printk's here are wrong because we are complaining that there is no2525- * output device, but printk is printing to that output device. The user will2626- * never see the error. printf would be better, except it can't run on a2727- * kernel stack because it will overflow it.2828- * Use printk for now since that will avoid crashing.2929- */2626+static int my_printf(const char * fmt, ...)2727+{2828+ /* Yes, can be called on atomic context.*/2929+ char *buf = kmalloc(4096, GFP_ATOMIC);3030+ va_list args;3131+ int r;3232+3333+ if (!buf) {3434+ /* We print directly fmt.3535+ * Yes, yes, yes, feel free to complain. */3636+ r = strlen(fmt);3737+ } else {3838+ va_start(args, fmt);3939+ r = vsprintf(buf, fmt, args);4040+ va_end(args);4141+ fmt = buf;4242+ }4343+4444+ if (r)4545+ r = os_write_file(1, fmt, r);4646+ return r;4747+4848+}4949+5050+#ifdef CONFIG_NOCONFIG_CHAN5151+/* Despite its name, there's no added trailing newline. */5252+static int my_puts(const char * buf)5353+{5454+ return os_write_file(1, buf, strlen(buf));5555+}30563157static void *not_configged_init(char *str, int device, struct chan_opts *opts)3258{3333- printk(KERN_ERR "Using a channel type which is configured out of "5959+ my_puts("Using a channel type which is configured out of "3460 "UML\n");3561 return(NULL);3662}···6438static int not_configged_open(int input, int output, int primary, void *data,6539 char **dev_out)6640{6767- printk(KERN_ERR "Using a channel type which is configured out of "4141+ my_puts("Using a channel type which is configured out of "6842 "UML\n");6943 return(-ENODEV);7044}71457246static void not_configged_close(int fd, void *data)7347{7474- printk(KERN_ERR "Using a channel type which is configured out of "4848+ my_puts("Using a channel type which is configured out of "7549 "UML\n");7650}77517852static int not_configged_read(int fd, char *c_out, void *data)7953{8080- printk(KERN_ERR "Using a channel type which is configured out of "5454+ my_puts("Using a channel type which is configured out of "8155 "UML\n");8256 return(-EIO);8357}84588559static int not_configged_write(int fd, const char *buf, int len, void *data)8660{8787- printk(KERN_ERR "Using a channel type which is configured out of "6161+ my_puts("Using a channel type which is configured out of "8862 "UML\n");8963 return(-EIO);9064}···9266static int not_configged_console_write(int fd, const char *buf, int len,9367 void *data)9468{9595- printk(KERN_ERR "Using a channel type which is configured out of "6969+ my_puts("Using a channel type which is configured out of "9670 "UML\n");9771 return(-EIO);9872}···10074static int not_configged_window_size(int fd, void *data, unsigned short *rows,10175 unsigned short *cols)10276{103103- printk(KERN_ERR "Using a channel type which is configured out of "7777+ my_puts("Using a channel type which is configured out of "10478 "UML\n");10579 return(-ENODEV);10680}1078110882static void not_configged_free(void *data)10983{110110- printf(KERN_ERR "Using a channel type which is configured out of "8484+ my_puts("Using a channel type which is configured out of "11185 "UML\n");11286}11387···483457 }484458 }485459 if(ops == NULL){486486- printk(KERN_ERR "parse_chan couldn't parse \"%s\"\n", 460460+ my_printf("parse_chan couldn't parse \"%s\"\n",487461 str);488462 return(NULL);489463 }···491465 data = (*ops->init)(str, device, opts);492466 if(data == NULL) return(NULL);493467494494- chan = kmalloc(sizeof(*chan), GFP_KERNEL);468468+ chan = kmalloc(sizeof(*chan), GFP_ATOMIC);495469 if(chan == NULL) return(NULL);496470 *chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list),497471 .primary = 1,
···1414extern void kfree(void *ptr);1515extern int in_aton(char *str);1616extern int open_gdb_chan(void);1717-extern int strlcpy(char *, const char *, int);1717+/* These use size_t, however unsigned long is correct on both i386 and x86_64. */1818+extern unsigned long strlcpy(char *, const char *, unsigned long);1919+extern unsigned long strlcat(char *, const char *, unsigned long);1820extern void *um_vmalloc(int size);1921extern void vfree(void *ptr);2022
+2-1
arch/um/kernel/process_kern.c
···8282 unsigned long page;8383 int flags = GFP_KERNEL;84848585- if(atomic) flags |= GFP_ATOMIC;8585+ if (atomic)8686+ flags = GFP_ATOMIC;8687 page = __get_free_pages(flags, order);8788 if(page == 0)8889 return(0);
+1-1
arch/um/kernel/sigio_user.c
···340340{341341 struct pollfd *p;342342343343- p = um_kmalloc(sizeof(struct pollfd));343343+ p = um_kmalloc_atomic(sizeof(struct pollfd));344344 if(p == NULL){345345 printk("setup_initial_poll : failed to allocate poll\n");346346 return(-1);
-6
arch/um/kernel/skas/include/uaccess-skas.h
···1818 ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \1919 ((unsigned long) (addr) + (size) >= (unsigned long)(addr))))20202121-static inline int verify_area_skas(int type, const void __user * addr,2222- unsigned long size)2323-{2424- return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);2525-}2626-2721extern int copy_from_user_skas(void *to, const void __user *from, int n);2822extern int copy_to_user_skas(void __user *to, const void *from, int n);2923extern int strncpy_from_user_skas(char *dst, const char __user *src, int count);
+6-6
arch/um/kernel/tlb.c
···193193 r = pte_read(*npte);194194 w = pte_write(*npte);195195 x = pte_exec(*npte);196196- if(!pte_dirty(*npte))197197- w = 0;198198- if(!pte_young(*npte)){199199- r = 0;200200- w = 0;201201- }196196+ if (!pte_young(*npte)) {197197+ r = 0;198198+ w = 0;199199+ } else if (!pte_dirty(*npte)) {200200+ w = 0;201201+ }202202 if(force || pte_newpage(*npte)){203203 if(pte_present(*npte))204204 ret = add_mmap(addr,
+17-1
arch/um/kernel/trap_kern.c
···1818#include "asm/a.out.h"1919#include "asm/current.h"2020#include "asm/irq.h"2121+#include "sysdep/sigcontext.h"2122#include "user_util.h"2223#include "kern_util.h"2324#include "kern.h"···4039 int err = -EFAULT;41404241 *code_out = SEGV_MAPERR;4242+4343+ /* If the fault was during atomic operation, don't take the fault, just4444+ * fail. */4545+ if (in_atomic())4646+ goto out_nosemaphore;4747+4348 down_read(&mm->mmap_sem);4449 vma = find_vma(mm, address);4550 if(!vma) ···9689 flush_tlb_page(vma, address);9790out:9891 up_read(&mm->mmap_sem);9292+out_nosemaphore:9993 return(err);1009410195/*···133125 }134126 else if(current->mm == NULL)135127 panic("Segfault with no mm");136136- err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);128128+129129+ if (SEGV_IS_FIXABLE(&fi))130130+ err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);131131+ else {132132+ err = -EFAULT;133133+ /* A thread accessed NULL, we get a fault, but CR2 is invalid.134134+ * This code is used in __do_copy_from_user() of TT mode. */135135+ address = 0;136136+ }137137138138 catcher = current->thread.fault_catcher;139139 if(!err)
-6
arch/um/kernel/tt/include/uaccess-tt.h
···3333 (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \3434 (under_task_size(addr, size) || is_stack(addr, size))))35353636-static inline int verify_area_tt(int type, const void __user * addr,3737- unsigned long size)3838-{3939- return(access_ok_tt(type, addr, size) ? 0 : -EFAULT);4040-}4141-4236extern unsigned long get_fault_addr(void);43374438extern int __do_copy_from_user(void *to, const void *from, int n,
···2222 __do_copy, &faulted);2323 TASK_REGS(get_current())->tt = save;24242525- if(!faulted) return(0);2626- else return(n - (fault - (unsigned long) from));2525+ if(!faulted)2626+ return 0;2727+ else if (fault)2828+ return n - (fault - (unsigned long) from);2929+ else3030+ /* In case of a general protection fault, we don't have the3131+ * fault address, so NULL is used instead. Pretend we didn't3232+ * copy anything. */3333+ return n;2734}28352936static void __do_strncpy(void *dst, const void *src, int count)
+23-18
arch/um/kernel/umid.c
···3131/* Changed by set_umid */3232static int umid_is_random = 1;3333static int umid_inited = 0;3434+/* Have we created the files? Should we remove them? */3535+static int umid_owned = 0;34363537static int make_umid(int (*printer)(const char *fmt, ...));3638···84828583extern int tracing_pid;86848787-static int __init create_pid_file(void)8585+static void __init create_pid_file(void)8886{8987 char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];9088 char pid[sizeof("nnnnn\0")];9189 int fd, n;92909393- if(umid_file_name("pid", file, sizeof(file))) return 0;9191+ if(umid_file_name("pid", file, sizeof(file)))9292+ return;94939594 fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 9695 0644);9796 if(fd < 0){9897 printf("Open of machine pid file \"%s\" failed: %s\n",9998 file, strerror(-fd));100100- return 0;9999+ return;101100 }102101103102 sprintf(pid, "%d\n", os_getpid());···106103 if(n != strlen(pid))107104 printf("Write of pid file failed - err = %d\n", -n);108105 os_close_file(fd);109109- return 0;110106}111107112108static int actually_do_remove(char *dir)···149147void remove_umid_dir(void)150148{151149 char dir[strlen(uml_dir) + UMID_LEN + 1];152152- if(!umid_inited) return;150150+ if (!umid_owned)151151+ return;153152154153 sprintf(dir, "%s%s", uml_dir, umid);155154 actually_do_remove(dir);···158155159156char *get_umid(int only_if_set)160157{161161- if(only_if_set && umid_is_random) return(NULL);162162- return(umid);158158+ if(only_if_set && umid_is_random)159159+ return NULL;160160+ return umid;163161}164162165165-int not_dead_yet(char *dir)163163+static int not_dead_yet(char *dir)166164{167165 char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];168166 char pid[sizeof("nnnnn\0")], *end;···197193 (p == CHOOSE_MODE(tracing_pid, os_getpid())))198194 dead = 1;199195 }200200- if(!dead) return(1);196196+ if(!dead)197197+ return(1);201198 return(actually_do_remove(dir));202199}203200···237232 strlcpy(dir, home, sizeof(dir));238233 uml_dir++;239234 }235235+ strlcat(dir, uml_dir, sizeof(dir));240236 len = strlen(dir);241241- strncat(dir, uml_dir, sizeof(dir) - len);242242- len = strlen(dir);243243- if((len > 0) && (len < sizeof(dir) - 1) && (dir[len - 1] != '/')){244244- dir[len] = '/';245245- dir[len + 1] = '\0';246246- }237237+ if (len > 0 && dir[len - 1] != '/')238238+ strlcat(dir, "/", sizeof(dir));247239248240 uml_dir = malloc(strlen(dir) + 1);249249- if(uml_dir == NULL){241241+ if (uml_dir == NULL) {250242 printf("make_uml_dir : malloc failed, errno = %d\n", errno);251243 exit(1);252244 }···288286 if(errno == EEXIST){289287 if(not_dead_yet(tmp)){290288 (*printer)("umid '%s' is in use\n", umid);289289+ umid_owned = 0;291290 return(-1);292291 }293292 err = mkdir(tmp, 0777);···299296 return(-1);300297 }301298302302- return(0);299299+ umid_owned = 1;300300+ return 0;303301}304302305303__uml_setup("uml_dir=", set_uml_dir,···313309 /* one function with the ordering we need ... */314310 make_uml_dir();315311 make_umid(printf);316316- return create_pid_file();312312+ create_pid_file();313313+ return 0;317314}318315__uml_postsetup(make_umid_setup);319316
···144144 "errno = %d\n", errno);145145 }146146 else {147147+ /* This is safe as we've just a pointer here. */147148 aio = (struct aio_context *) (long) event.data;148149 if(update_aio(aio, event.res)){149150 do_aio(ctx, aio);
+2-1
arch/um/os-Linux/elf_aux.c
···1414#include "mem_user.h"1515#include <kernel-offsets.h>16161717-#if HOST_ELF_CLASS == ELFCLASS321717+/* Use the one from the kernel - the host may miss it, if having old headers. */1818+#if UM_ELF_CLASS == UM_ELFCLASS321819typedef Elf32_auxv_t elf_auxv_t;1920#else2021typedef Elf64_auxv_t elf_auxv_t;
+1
arch/um/os-Linux/process.c
···33 * Licensed under the GPL44 */5566+#include <unistd.h>67#include <stdio.h>78#include <errno.h>89#include <signal.h>
···308308 present. The HPET provides a stable time base on SMP309309 systems, unlike the TSC, but it is more expensive to access,310310 as it is off-chip. You can find the HPET spec at311311- <http://www.intel.com/labs/platcomp/hpet/hpetspec.htm>.311311+ <http://www.intel.com/hardwaredesign/hpetspec.htm>.312312313313config X86_PM_TIMER314314 bool "PM timer"
···457457dump_task_fpu(struct pt_regs *regs, struct task_struct *task, elf_fpregset_t *r)458458{459459/* see asm/coprocessor.h for this magic number 16 */460460-#if TOTAL_CPEXTRA_SIZE > 16460460+#if XTENSA_CP_EXTRA_SIZE > 16461461 do_save_fpregs (r, regs, task);462462463463 /* For now, bit 16 means some extra state may be present: */
···6868 * speed for the CALIBRATE.6969 */70707171-#if CONFIG_XTENSA_CALIBRATE_CCOUNT7171+#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT7272 printk("Calibrating CPU frequency ");7373 platform_calibrate_ccount();7474 printk("%d.%02d MHz\n", (int)ccount_per_jiffy/(1000000/HZ),
+1-1
arch/xtensa/mm/init.c
···239239 high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);240240 highmemsize = 0;241241242242-#if CONFIG_HIGHMEM242242+#ifdef CONFIG_HIGHMEM243243#error HIGHGMEM not implemented in init.c244244#endif245245
···26202620 spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);26212621 if (!list_empty(&(intf->waiting_msgs))) {26222622 list_add_tail(&(msg->link), &(intf->waiting_msgs));26232623- spin_unlock(&(intf->waiting_msgs_lock));26232623+ spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);26242624 goto out_unlock;26252625 }26262626 spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);···26292629 if (rv > 0) {26302630 /* Could not handle the message now, just add it to a26312631 list to handle later. */26322632- spin_lock(&(intf->waiting_msgs_lock));26322632+ spin_lock_irqsave(&(intf->waiting_msgs_lock), flags);26332633 list_add_tail(&(msg->link), &(intf->waiting_msgs));26342634- spin_unlock(&(intf->waiting_msgs_lock));26342634+ spin_unlock_irqrestore(&(intf->waiting_msgs_lock), flags);26352635 } else if (rv == 0) {26362636 ipmi_free_smi_msg(msg);26372637 }
+4-5
drivers/hwmon/Kconfig
···418418 help419419 This driver provides support for the IBM Hard Drive Active Protection420420 System (hdaps), which provides an accelerometer and other misc. data.421421- Supported laptops include the IBM ThinkPad T41, T42, T43, and R51.422422- The accelerometer data is readable via sysfs.421421+ ThinkPads starting with the R50, T41, and X40 are supported. The422422+ accelerometer data is readable via sysfs.423423424424- This driver also provides an input class device, allowing the425425- laptop to act as a pinball machine-esque mouse. This is off by426426- default but enabled via sysfs or the module parameter "mousedev".424424+ This driver also provides an absolute input class device, allowing425425+ the laptop to act as a pinball machine-esque joystick.427426428427 Say Y here if you have an applicable laptop and want to experience429428 the awesome power of hdaps.
+9-12
drivers/hwmon/hdaps.c
···44 * Copyright (C) 2005 Robert Love <rml@novell.com>55 * Copyright (C) 2005 Jesper Juhl <jesper.juhl@gmail.com>66 *77- * The HardDisk Active Protection System (hdaps) is present in the IBM ThinkPad88- * T41, T42, T43, R50, R50p, R51, and X40, at least. It provides a basic99- * two-axis accelerometer and other data, such as the device's temperature.77+ * The HardDisk Active Protection System (hdaps) is present in IBM ThinkPads88+ * starting with the R40, T41, and X40. It provides a basic two-axis99+ * accelerometer and other data, such as the device's temperature.1010 *1111 * This driver is based on the document by Mark A. Smith available at1212 * http://www.almaden.ibm.com/cs/people/marksmith/tpaps.html and a lot of trial···487487488488/* Module stuff */489489490490-/*491491- * XXX: We should be able to return nonzero and halt the detection process.492492- * But there is a bug in dmi_check_system() where a nonzero return from the493493- * first match will result in a return of failure from dmi_check_system().494494- * I fixed this; the patch is 2.6-git. Once in a released tree, we can make495495- * hdaps_dmi_match_invert() return hdaps_dmi_match(), which in turn returns 1.496496- */490490+/* hdaps_dmi_match - found a match. return one, short-circuiting the hunt. */497491static int hdaps_dmi_match(struct dmi_system_id *id)498492{499493 printk(KERN_INFO "hdaps: %s detected.\n", id->ident);500500- return 0;494494+ return 1;501495}502496497497+/* hdaps_dmi_match_invert - found an inverted match. */503498static int hdaps_dmi_match_invert(struct dmi_system_id *id)504499{505500 hdaps_invert = 1;506501 printk(KERN_INFO "hdaps: inverting axis readings.\n");507507- return 0;502502+ return hdaps_dmi_match(id);508503}509504510505#define HDAPS_DMI_MATCH_NORMAL(model) { \···529534 HDAPS_DMI_MATCH_INVERT("ThinkPad R50p"),530535 HDAPS_DMI_MATCH_NORMAL("ThinkPad R50"),531536 HDAPS_DMI_MATCH_NORMAL("ThinkPad R51"),537537+ HDAPS_DMI_MATCH_NORMAL("ThinkPad R52"),532538 HDAPS_DMI_MATCH_INVERT("ThinkPad T41p"),533539 HDAPS_DMI_MATCH_NORMAL("ThinkPad T41"),534540 HDAPS_DMI_MATCH_INVERT("ThinkPad T42p"),···537541 HDAPS_DMI_MATCH_NORMAL("ThinkPad T43"),538542 HDAPS_DMI_MATCH_NORMAL("ThinkPad X40"),539543 HDAPS_DMI_MATCH_NORMAL("ThinkPad X41 Tablet"),544544+ HDAPS_DMI_MATCH_NORMAL("ThinkPad X41"),540545 { .ident = NULL }541546 };542547
+12
drivers/i2c/busses/Kconfig
···245245 This support is also available as a module. If so, the module 246246 will be called i2c-keywest.247247248248+config I2C_PMAC_SMU249249+ tristate "Powermac SMU I2C interface"250250+ depends on I2C && PMAC_SMU251251+ help252252+ This supports the use of the I2C interface in the SMU253253+ chip on recent Apple machines like the iMac G5. It is used254254+ among others by the thermal control driver for those machines.255255+ Say Y if you have such a machine.256256+257257+ This support is also available as a module. If so, the module258258+ will be called i2c-pmac-smu.259259+248260config I2C_MPC249261 tristate "MPC107/824x/85xx/52xx"250262 depends on I2C && PPC32
···11+/*22+ i2c Support for Apple SMU Controller33+44+ Copyright (c) 2005 Benjamin Herrenschmidt, IBM Corp.55+ <benh@kernel.crashing.org>66+77+ This program is free software; you can redistribute it and/or modify88+ it under the terms of the GNU General Public License as published by99+ the Free Software Foundation; either version 2 of the License, or1010+ (at your option) any later version.1111+1212+ This program is distributed in the hope that it will be useful,1313+ but WITHOUT ANY WARRANTY; without even the implied warranty of1414+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1515+ GNU General Public License for more details.1616+1717+ You should have received a copy of the GNU General Public License1818+ along with this program; if not, write to the Free Software1919+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.2020+2121+*/2222+2323+#include <linux/config.h>2424+#include <linux/module.h>2525+#include <linux/kernel.h>2626+#include <linux/types.h>2727+#include <linux/i2c.h>2828+#include <linux/init.h>2929+#include <linux/completion.h>3030+#include <linux/device.h>3131+#include <asm/prom.h>3232+#include <asm/of_device.h>3333+#include <asm/smu.h>3434+3535+static int probe;3636+3737+MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");3838+MODULE_DESCRIPTION("I2C driver for Apple's SMU");3939+MODULE_LICENSE("GPL");4040+module_param(probe, bool, 0);4141+4242+4343+/* Physical interface */4444+struct smu_iface4545+{4646+ struct i2c_adapter adapter;4747+ struct completion complete;4848+ u32 busid;4949+};5050+5151+static void smu_i2c_done(struct smu_i2c_cmd *cmd, void *misc)5252+{5353+ struct smu_iface *iface = misc;5454+ complete(&iface->complete);5555+}5656+5757+/*5858+ * SMBUS-type transfer entrypoint5959+ */6060+static s32 smu_smbus_xfer( struct i2c_adapter* adap,6161+ u16 addr,6262+ unsigned short flags,6363+ char read_write,6464+ u8 command,6565+ int size,6666+ union i2c_smbus_data* data)6767+{6868+ struct smu_iface *iface = i2c_get_adapdata(adap);6969+ struct smu_i2c_cmd cmd;7070+ int rc = 0;7171+ int read = (read_write == I2C_SMBUS_READ);7272+7373+ cmd.info.bus = iface->busid;7474+ cmd.info.devaddr = (addr << 1) | (read ? 0x01 : 0x00);7575+7676+ /* Prepare datas & select mode */7777+ switch (size) {7878+ case I2C_SMBUS_QUICK:7979+ cmd.info.type = SMU_I2C_TRANSFER_SIMPLE;8080+ cmd.info.datalen = 0;8181+ break;8282+ case I2C_SMBUS_BYTE:8383+ cmd.info.type = SMU_I2C_TRANSFER_SIMPLE;8484+ cmd.info.datalen = 1;8585+ if (!read)8686+ cmd.info.data[0] = data->byte;8787+ break;8888+ case I2C_SMBUS_BYTE_DATA:8989+ cmd.info.type = SMU_I2C_TRANSFER_STDSUB;9090+ cmd.info.datalen = 1;9191+ cmd.info.sublen = 1;9292+ cmd.info.subaddr[0] = command;9393+ cmd.info.subaddr[1] = 0;9494+ cmd.info.subaddr[2] = 0;9595+ if (!read)9696+ cmd.info.data[0] = data->byte;9797+ break;9898+ case I2C_SMBUS_WORD_DATA:9999+ cmd.info.type = SMU_I2C_TRANSFER_STDSUB;100100+ cmd.info.datalen = 2;101101+ cmd.info.sublen = 1;102102+ cmd.info.subaddr[0] = command;103103+ cmd.info.subaddr[1] = 0;104104+ cmd.info.subaddr[2] = 0;105105+ if (!read) {106106+ cmd.info.data[0] = data->byte & 0xff;107107+ cmd.info.data[1] = (data->byte >> 8) & 0xff;108108+ }109109+ break;110110+ /* Note that these are broken vs. the expected smbus API where111111+ * on reads, the lenght is actually returned from the function,112112+ * but I think the current API makes no sense and I don't want113113+ * any driver that I haven't verified for correctness to go114114+ * anywhere near a pmac i2c bus anyway ...115115+ */116116+ case I2C_SMBUS_BLOCK_DATA:117117+ cmd.info.type = SMU_I2C_TRANSFER_STDSUB;118118+ cmd.info.datalen = data->block[0] + 1;119119+ if (cmd.info.datalen > 6)120120+ return -EINVAL;121121+ if (!read)122122+ memcpy(cmd.info.data, data->block, cmd.info.datalen);123123+ cmd.info.sublen = 1;124124+ cmd.info.subaddr[0] = command;125125+ cmd.info.subaddr[1] = 0;126126+ cmd.info.subaddr[2] = 0;127127+ break;128128+ case I2C_SMBUS_I2C_BLOCK_DATA:129129+ cmd.info.type = SMU_I2C_TRANSFER_STDSUB;130130+ cmd.info.datalen = data->block[0];131131+ if (cmd.info.datalen > 7)132132+ return -EINVAL;133133+ if (!read)134134+ memcpy(cmd.info.data, &data->block[1],135135+ cmd.info.datalen);136136+ cmd.info.sublen = 1;137137+ cmd.info.subaddr[0] = command;138138+ cmd.info.subaddr[1] = 0;139139+ cmd.info.subaddr[2] = 0;140140+ break;141141+142142+ default:143143+ return -EINVAL;144144+ }145145+146146+ /* Turn a standardsub read into a combined mode access */147147+ if (read_write == I2C_SMBUS_READ &&148148+ cmd.info.type == SMU_I2C_TRANSFER_STDSUB)149149+ cmd.info.type = SMU_I2C_TRANSFER_COMBINED;150150+151151+ /* Finish filling command and submit it */152152+ cmd.done = smu_i2c_done;153153+ cmd.misc = iface;154154+ rc = smu_queue_i2c(&cmd);155155+ if (rc < 0)156156+ return rc;157157+ wait_for_completion(&iface->complete);158158+ rc = cmd.status;159159+160160+ if (!read || rc < 0)161161+ return rc;162162+163163+ switch (size) {164164+ case I2C_SMBUS_BYTE:165165+ case I2C_SMBUS_BYTE_DATA:166166+ data->byte = cmd.info.data[0];167167+ break;168168+ case I2C_SMBUS_WORD_DATA:169169+ data->word = ((u16)cmd.info.data[1]) << 8;170170+ data->word |= cmd.info.data[0];171171+ break;172172+ /* Note that these are broken vs. the expected smbus API where173173+ * on reads, the lenght is actually returned from the function,174174+ * but I think the current API makes no sense and I don't want175175+ * any driver that I haven't verified for correctness to go176176+ * anywhere near a pmac i2c bus anyway ...177177+ */178178+ case I2C_SMBUS_BLOCK_DATA:179179+ case I2C_SMBUS_I2C_BLOCK_DATA:180180+ memcpy(&data->block[0], cmd.info.data, cmd.info.datalen);181181+ break;182182+ }183183+184184+ return rc;185185+}186186+187187+static u32188188+smu_smbus_func(struct i2c_adapter * adapter)189189+{190190+ return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE |191191+ I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA |192192+ I2C_FUNC_SMBUS_BLOCK_DATA;193193+}194194+195195+/* For now, we only handle combined mode (smbus) */196196+static struct i2c_algorithm smu_algorithm = {197197+ .smbus_xfer = smu_smbus_xfer,198198+ .functionality = smu_smbus_func,199199+};200200+201201+static int create_iface(struct device_node *np, struct device *dev)202202+{203203+ struct smu_iface* iface;204204+ u32 *reg, busid;205205+ int rc;206206+207207+ reg = (u32 *)get_property(np, "reg", NULL);208208+ if (reg == NULL) {209209+ printk(KERN_ERR "i2c-pmac-smu: can't find bus number !\n");210210+ return -ENXIO;211211+ }212212+ busid = *reg;213213+214214+ iface = kmalloc(sizeof(struct smu_iface), GFP_KERNEL);215215+ if (iface == NULL) {216216+ printk(KERN_ERR "i2c-pmac-smu: can't allocate inteface !\n");217217+ return -ENOMEM;218218+ }219219+ memset(iface, 0, sizeof(struct smu_iface));220220+ init_completion(&iface->complete);221221+ iface->busid = busid;222222+223223+ dev_set_drvdata(dev, iface);224224+225225+ sprintf(iface->adapter.name, "smu-i2c-%02x", busid);226226+ iface->adapter.algo = &smu_algorithm;227227+ iface->adapter.algo_data = NULL;228228+ iface->adapter.client_register = NULL;229229+ iface->adapter.client_unregister = NULL;230230+ i2c_set_adapdata(&iface->adapter, iface);231231+ iface->adapter.dev.parent = dev;232232+233233+ rc = i2c_add_adapter(&iface->adapter);234234+ if (rc) {235235+ printk(KERN_ERR "i2c-pamc-smu.c: Adapter %s registration "236236+ "failed\n", iface->adapter.name);237237+ i2c_set_adapdata(&iface->adapter, NULL);238238+ }239239+240240+ if (probe) {241241+ unsigned char addr;242242+ printk("Probe: ");243243+ for (addr = 0x00; addr <= 0x7f; addr++) {244244+ if (i2c_smbus_xfer(&iface->adapter,addr,245245+ 0,0,0,I2C_SMBUS_QUICK,NULL) >= 0)246246+ printk("%02x ", addr);247247+ }248248+ printk("\n");249249+ }250250+251251+ printk(KERN_INFO "SMU i2c bus %x registered\n", busid);252252+253253+ return 0;254254+}255255+256256+static int dispose_iface(struct device *dev)257257+{258258+ struct smu_iface *iface = dev_get_drvdata(dev);259259+ int rc;260260+261261+ rc = i2c_del_adapter(&iface->adapter);262262+ i2c_set_adapdata(&iface->adapter, NULL);263263+ /* We aren't that prepared to deal with this... */264264+ if (rc)265265+ printk("i2c-pmac-smu.c: Failed to remove bus %s !\n",266266+ iface->adapter.name);267267+ dev_set_drvdata(dev, NULL);268268+ kfree(iface);269269+270270+ return 0;271271+}272272+273273+274274+static int create_iface_of_platform(struct of_device* dev,275275+ const struct of_device_id *match)276276+{277277+ return create_iface(dev->node, &dev->dev);278278+}279279+280280+281281+static int dispose_iface_of_platform(struct of_device* dev)282282+{283283+ return dispose_iface(&dev->dev);284284+}285285+286286+287287+static struct of_device_id i2c_smu_match[] =288288+{289289+ {290290+ .compatible = "smu-i2c",291291+ },292292+ {},293293+};294294+static struct of_platform_driver i2c_smu_of_platform_driver =295295+{296296+ .name = "i2c-smu",297297+ .match_table = i2c_smu_match,298298+ .probe = create_iface_of_platform,299299+ .remove = dispose_iface_of_platform300300+};301301+302302+303303+static int __init i2c_pmac_smu_init(void)304304+{305305+ of_register_driver(&i2c_smu_of_platform_driver);306306+ return 0;307307+}308308+309309+310310+static void __exit i2c_pmac_smu_cleanup(void)311311+{312312+ of_unregister_driver(&i2c_smu_of_platform_driver);313313+}314314+315315+module_init(i2c_pmac_smu_init);316316+module_exit(i2c_pmac_smu_cleanup);
+8-11
drivers/infiniband/core/mad_rmpp.c
···412412413413 hdr_size = data_offset(rmpp_mad->mad_hdr.mgmt_class);414414 data_size = sizeof(struct ib_rmpp_mad) - hdr_size;415415- pad = data_size - be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);416416- if (pad > data_size || pad < 0)415415+ pad = IB_MGMT_RMPP_DATA - be32_to_cpu(rmpp_mad->rmpp_hdr.paylen_newwin);416416+ if (pad > IB_MGMT_RMPP_DATA || pad < 0)417417 pad = 0;418418419419 return hdr_size + rmpp_recv->seg_num * data_size - pad;···583583{584584 struct ib_rmpp_mad *rmpp_mad;585585 int timeout;586586+ u32 paylen;586587587588 rmpp_mad = (struct ib_rmpp_mad *)mad_send_wr->send_wr.wr.ud.mad_hdr;588589 ib_set_rmpp_flags(&rmpp_mad->rmpp_hdr, IB_MGMT_RMPP_FLAG_ACTIVE);···591590592591 if (mad_send_wr->seg_num == 1) {593592 rmpp_mad->rmpp_hdr.rmpp_rtime_flags |= IB_MGMT_RMPP_FLAG_FIRST;594594- rmpp_mad->rmpp_hdr.paylen_newwin =595595- cpu_to_be32(mad_send_wr->total_seg *596596- (sizeof(struct ib_rmpp_mad) -597597- offsetof(struct ib_rmpp_mad, data)) -598598- mad_send_wr->pad);593593+ paylen = mad_send_wr->total_seg * IB_MGMT_RMPP_DATA -594594+ mad_send_wr->pad;595595+ rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(paylen);599596 mad_send_wr->sg_list[0].length = sizeof(struct ib_rmpp_mad);600597 } else {601598 mad_send_wr->send_wr.num_sge = 2;···607608608609 if (mad_send_wr->seg_num == mad_send_wr->total_seg) {609610 rmpp_mad->rmpp_hdr.rmpp_rtime_flags |= IB_MGMT_RMPP_FLAG_LAST;610610- rmpp_mad->rmpp_hdr.paylen_newwin =611611- cpu_to_be32(sizeof(struct ib_rmpp_mad) -612612- offsetof(struct ib_rmpp_mad, data) -613613- mad_send_wr->pad);611611+ paylen = IB_MGMT_RMPP_DATA - mad_send_wr->pad;612612+ rmpp_mad->rmpp_hdr.paylen_newwin = cpu_to_be32(paylen);614613 }615614616615 /* 2 seconds for an ACK until we can find the packet lifetime */
+3-2
drivers/infiniband/core/user_mad.c
···334334 ret = -EINVAL;335335 goto err_ah;336336 }337337- /* Validate that management class can support RMPP */337337+338338+ /* Validate that the management class can support RMPP */338339 if (rmpp_mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_ADM) {339340 hdr_len = offsetof(struct ib_sa_mad, data);340340- data_len = length;341341+ data_len = length - hdr_len;341342 } else if ((rmpp_mad->mad_hdr.mgmt_class >= IB_MGMT_CLASS_VENDOR_RANGE2_START) &&342343 (rmpp_mad->mad_hdr.mgmt_class <= IB_MGMT_CLASS_VENDOR_RANGE2_END)) {343344 hdr_len = offsetof(struct ib_vendor_mad, data);
+5-11
drivers/infiniband/hw/mthca/mthca_eq.c
···476476 int i;477477 u8 status;478478479479- /* Make sure EQ size is aligned to a power of 2 size. */480480- for (i = 1; i < nent; i <<= 1)481481- ; /* nothing */482482- nent = i;483483-484484- eq->dev = dev;479479+ eq->dev = dev;480480+ eq->nent = roundup_pow_of_two(max(nent, 2));485481486482 eq->page_list = kmalloc(npages * sizeof *eq->page_list,487483 GFP_KERNEL);···508512 memset(eq->page_list[i].buf, 0, PAGE_SIZE);509513 }510514511511- for (i = 0; i < nent; ++i)515515+ for (i = 0; i < eq->nent; ++i)512516 set_eqe_hw(get_eqe(eq, i));513517514518 eq->eqn = mthca_alloc(&dev->eq_table.alloc);···524528 if (err)525529 goto err_out_free_eq;526530527527- eq->nent = nent;528528-529531 memset(eq_context, 0, sizeof *eq_context);530532 eq_context->flags = cpu_to_be32(MTHCA_EQ_STATUS_OK |531533 MTHCA_EQ_OWNER_HW |···532538 if (mthca_is_memfree(dev))533539 eq_context->flags |= cpu_to_be32(MTHCA_EQ_STATE_ARBEL);534540535535- eq_context->logsize_usrpage = cpu_to_be32((ffs(nent) - 1) << 24);541541+ eq_context->logsize_usrpage = cpu_to_be32((ffs(eq->nent) - 1) << 24);536542 if (mthca_is_memfree(dev)) {537543 eq_context->arbel_pd = cpu_to_be32(dev->driver_pd.pd_num);538544 } else {···563569 dev->eq_table.arm_mask |= eq->eqn_mask;564570565571 mthca_dbg(dev, "Allocated EQ %d with %d entries\n",566566- eq->eqn, nent);572572+ eq->eqn, eq->nent);567573568574 return err;569575
···432432 flush_workqueue(ipoib_workqueue);433433 }434434435435- ipoib_mcast_stop_thread(dev);435435+ ipoib_mcast_stop_thread(dev, 1);436436437437 /*438438 * Flush the multicast groups first so we stop any multicast joins. The···599599600600 ipoib_dbg(priv, "cleaning up ib_dev\n");601601602602- ipoib_mcast_stop_thread(dev);602602+ ipoib_mcast_stop_thread(dev, 1);603603604604 /* Delete the broadcast address and the local address */605605 ipoib_mcast_dev_down(dev);
···209209 bcs->mode = mode;210210211211 // Cancel all USB transfers on this B channel212212- b_out->urb[0]->transfer_flags |= URB_ASYNC_UNLINK;213212 usb_unlink_urb(b_out->urb[0]);214214- b_out->urb[1]->transfer_flags |= URB_ASYNC_UNLINK;215213 usb_unlink_urb(b_out->urb[1]);216214 b_out->busy = 0;217215
···763763 /* no PLL needed */764764 if (btv->pll.pll_current == 0)765765 return;766766- vprintk(KERN_INFO "bttv%d: PLL can sleep, using XTAL (%d).\n",767767- btv->c.nr,btv->pll.pll_ifreq);766766+ bttv_printk(KERN_INFO "bttv%d: PLL can sleep, using XTAL (%d).\n",767767+ btv->c.nr,btv->pll.pll_ifreq);768768 btwrite(0x00,BT848_TGCTRL);769769 btwrite(0x00,BT848_PLL_XCI);770770 btv->pll.pll_current = 0;771771 return;772772 }773773774774- vprintk(KERN_INFO "bttv%d: PLL: %d => %d ",btv->c.nr,775775- btv->pll.pll_ifreq, btv->pll.pll_ofreq);774774+ bttv_printk(KERN_INFO "bttv%d: PLL: %d => %d ",btv->c.nr,775775+ btv->pll.pll_ifreq, btv->pll.pll_ofreq);776776 set_pll_freq(btv, btv->pll.pll_ifreq, btv->pll.pll_ofreq);777777778778 for (i=0; i<10; i++) {779779 /* Let other people run while the PLL stabilizes */780780- vprintk(".");780780+ bttv_printk(".");781781 msleep(10);782782783783 if (btread(BT848_DSTATUS) & BT848_DSTATUS_PLOCK) {···785785 } else {786786 btwrite(0x08,BT848_TGCTRL);787787 btv->pll.pll_current = btv->pll.pll_ofreq;788788- vprintk(" ok\n");788788+ bttv_printk(" ok\n");789789 return;790790 }791791 }792792 btv->pll.pll_current = -1;793793- vprintk("failed\n");793793+ bttv_printk("failed\n");794794 return;795795}796796
+1-1
drivers/media/video/bttvp.h
···221221extern int init_bttv_i2c(struct bttv *btv);222222extern int fini_bttv_i2c(struct bttv *btv);223223224224-#define vprintk if (bttv_verbose) printk224224+#define bttv_printk if (bttv_verbose) printk225225#define dprintk if (bttv_debug >= 1) printk226226#define d2printk if (bttv_debug >= 2) printk227227
+17
drivers/message/fusion/Kconfig
···3535 LSIFC929X3636 LSIFC929XL37373838+config FUSION_SAS3939+ tristate "Fusion MPT ScsiHost drivers for SAS"4040+ depends on PCI && SCSI4141+ select FUSION4242+ select SCSI_SAS_ATTRS4343+ ---help---4444+ SCSI HOST support for a SAS host adapters.4545+4646+ List of supported controllers:4747+4848+ LSISAS10644949+ LSISAS10665050+ LSISAS10685151+ LSISAS1064E5252+ LSISAS1066E5353+ LSISAS1068E5454+3855config FUSION_MAX_SGE3956 int "Maximum number of scatter gather entries (16 - 128)"4057 depends on FUSION
···4848 u16 x_res;4949 u16 y_res;50505151- int restart:1;5252- int adcsync:1;5151+ unsigned int restart:1;5252+ unsigned int adcsync:1;5353};54545555static int adcsync;
+4-4
drivers/mtd/devices/docecc.c
···4040#include <linux/mtd/mtd.h>4141#include <linux/mtd/doc2000.h>42424343-#define DEBUG 04343+#define DEBUG_ECC 04444/* need to undef it (from asm/termbits.h) */4545#undef B04646···249249 lambda[j] ^= Alpha_to[modnn(u + tmp)];250250 }251251 }252252-#if DEBUG >= 1252252+#if DEBUG_ECC >= 1253253 /* Test code that verifies the erasure locator polynomial just constructed254254 Needed only for decoder debugging. */255255···276276 count = -1;277277 goto finish;278278 }279279-#if DEBUG >= 2279279+#if DEBUG_ECC >= 2280280 printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n");281281 for (i = 0; i < count; i++)282282 printf("%d ", loc[i]);···409409 den ^= Alpha_to[modnn(lambda[i+1] + i * root[j])];410410 }411411 if (den == 0) {412412-#if DEBUG >= 1412412+#if DEBUG_ECC >= 1413413 printf("\n ERROR: denominator = 0\n");414414#endif415415 /* Convert to dual- basis */
+1-1
drivers/net/8390.c
···1094109410951095 outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD);1096109610971097- if (inb_p(e8390_base) & E8390_TRANS) 10971097+ if (inb_p(e8390_base + E8390_CMD) & E8390_TRANS) 10981098 {10991099 printk(KERN_WARNING "%s: trigger_send() called with the transmitter busy.\n",11001100 dev->name);
+2-1
drivers/net/bonding/bond_main.c
···16531653 int old_features = bond_dev->features;16541654 int res = 0;1655165516561656- if (slave_dev->do_ioctl == NULL) {16561656+ if (!bond->params.use_carrier && slave_dev->ethtool_ops == NULL &&16571657+ slave_dev->do_ioctl == NULL) {16571658 printk(KERN_WARNING DRV_NAME16581659 ": Warning : no link monitoring support for %s\n",16591660 slave_dev->name);
···165165 if (l == 0xffffffff)166166 l = 0;167167 if ((l & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) {168168- sz = pci_size(l, sz, PCI_BASE_ADDRESS_MEM_MASK);168168+ sz = pci_size(l, sz, (u32)PCI_BASE_ADDRESS_MEM_MASK);169169 if (!sz)170170 continue;171171 res->start = l & PCI_BASE_ADDRESS_MEM_MASK;···215215 if (l == 0xffffffff)216216 l = 0;217217 if (sz && sz != 0xffffffff) {218218- sz = pci_size(l, sz, PCI_ROM_ADDRESS_MASK);218218+ sz = pci_size(l, sz, (u32)PCI_ROM_ADDRESS_MASK);219219 if (sz) {220220 res->flags = (l & IORESOURCE_ROM_ENABLE) |221221 IORESOURCE_MEM | IORESOURCE_PREFETCH |···402402static void __devinit pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max)403403{404404 struct pci_bus *parent = child->parent;405405+406406+ /* Attempts to fix that up are really dangerous unless407407+ we're going to re-assign all bus numbers. */408408+ if (!pcibios_assign_all_busses())409409+ return;410410+405411 while (parent->parent && parent->subordinate < max) {406412 parent->subordinate = max;407413 pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, max);···484478 * We need to assign a number to this bus which we always485479 * do in the second pass.486480 */487487- if (!pass)481481+ if (!pass) {482482+ if (pcibios_assign_all_busses())483483+ /* Temporarily disable forwarding of the484484+ configuration cycles on all bridges in485485+ this bus segment to avoid possible486486+ conflicts in the second pass between two487487+ bridges programmed with overlapping488488+ bus ranges. */489489+ pci_write_config_dword(dev, PCI_PRIMARY_BUS,490490+ buses & ~0xffffff);488491 return max;492492+ }489493490494 /* Clear errors */491495 pci_write_config_word(dev, PCI_STATUS, 0xffff);
+1-1
drivers/s390/cio/ccwgroup.c
···437437 if (cdev->dev.driver_data) {438438 gdev = (struct ccwgroup_device *)cdev->dev.driver_data;439439 if (get_device(&gdev->dev)) {440440- if (klist_node_attached(&gdev->dev.knode_bus))440440+ if (device_is_registered(&gdev->dev))441441 return gdev;442442 put_device(&gdev->dev);443443 }
···122122123123#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER124124125125-static inline int126126-zfcp_fsf_req_is_scsi_cmnd(struct zfcp_fsf_req *fsf_req)127127-{128128- return ((fsf_req->fsf_command == FSF_QTCB_FCP_CMND) &&129129- !(fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT));130130-}131131-132132-void133133-zfcp_cmd_dbf_event_fsf(const char *text, struct zfcp_fsf_req *fsf_req,134134- void *add_data, int add_length)135135-{136136- struct zfcp_adapter *adapter = fsf_req->adapter;137137- struct scsi_cmnd *scsi_cmnd;138138- int level = 3;139139- int i;140140- unsigned long flags;141141-142142- spin_lock_irqsave(&adapter->dbf_lock, flags);143143- if (zfcp_fsf_req_is_scsi_cmnd(fsf_req)) {144144- scsi_cmnd = fsf_req->data.send_fcp_command_task.scsi_cmnd;145145- debug_text_event(adapter->cmd_dbf, level, "fsferror");146146- debug_text_event(adapter->cmd_dbf, level, text);147147- debug_event(adapter->cmd_dbf, level, &fsf_req,148148- sizeof (unsigned long));149149- debug_event(adapter->cmd_dbf, level, &fsf_req->seq_no,150150- sizeof (u32));151151- debug_event(adapter->cmd_dbf, level, &scsi_cmnd,152152- sizeof (unsigned long));153153- debug_event(adapter->cmd_dbf, level, &scsi_cmnd->cmnd,154154- min(ZFCP_CMD_DBF_LENGTH, (int)scsi_cmnd->cmd_len));155155- for (i = 0; i < add_length; i += ZFCP_CMD_DBF_LENGTH)156156- debug_event(adapter->cmd_dbf,157157- level,158158- (char *) add_data + i,159159- min(ZFCP_CMD_DBF_LENGTH, add_length - i));160160- }161161- spin_unlock_irqrestore(&adapter->dbf_lock, flags);162162-}163163-164164-/* XXX additionally log unit if available */165165-/* ---> introduce new parameter for unit, see 2.4 code */166166-void167167-zfcp_cmd_dbf_event_scsi(const char *text, struct scsi_cmnd *scsi_cmnd)168168-{169169- struct zfcp_adapter *adapter;170170- union zfcp_req_data *req_data;171171- struct zfcp_fsf_req *fsf_req;172172- int level = ((host_byte(scsi_cmnd->result) != 0) ? 1 : 5);173173- unsigned long flags;174174-175175- adapter = (struct zfcp_adapter *) scsi_cmnd->device->host->hostdata[0];176176- req_data = (union zfcp_req_data *) scsi_cmnd->host_scribble;177177- fsf_req = (req_data ? req_data->send_fcp_command_task.fsf_req : NULL);178178- spin_lock_irqsave(&adapter->dbf_lock, flags);179179- debug_text_event(adapter->cmd_dbf, level, "hostbyte");180180- debug_text_event(adapter->cmd_dbf, level, text);181181- debug_event(adapter->cmd_dbf, level, &scsi_cmnd->result, sizeof (u32));182182- debug_event(adapter->cmd_dbf, level, &scsi_cmnd,183183- sizeof (unsigned long));184184- debug_event(adapter->cmd_dbf, level, &scsi_cmnd->cmnd,185185- min(ZFCP_CMD_DBF_LENGTH, (int)scsi_cmnd->cmd_len));186186- if (likely(fsf_req)) {187187- debug_event(adapter->cmd_dbf, level, &fsf_req,188188- sizeof (unsigned long));189189- debug_event(adapter->cmd_dbf, level, &fsf_req->seq_no,190190- sizeof (u32));191191- } else {192192- debug_text_event(adapter->cmd_dbf, level, "");193193- debug_text_event(adapter->cmd_dbf, level, "");194194- }195195- spin_unlock_irqrestore(&adapter->dbf_lock, flags);196196-}197197-198198-void199199-zfcp_in_els_dbf_event(struct zfcp_adapter *adapter, const char *text,200200- struct fsf_status_read_buffer *status_buffer, int length)201201-{202202- int level = 1;203203- int i;204204-205205- debug_text_event(adapter->in_els_dbf, level, text);206206- debug_event(adapter->in_els_dbf, level, &status_buffer->d_id, 8);207207- for (i = 0; i < length; i += ZFCP_IN_ELS_DBF_LENGTH)208208- debug_event(adapter->in_els_dbf,209209- level,210210- (char *) status_buffer->payload + i,211211- min(ZFCP_IN_ELS_DBF_LENGTH, length - i));212212-}213213-214125/**215126 * zfcp_device_setup - setup function216127 * @str: pointer to parameter string···9281017 mempool_destroy(adapter->pool.data_gid_pn);9291018}9301019931931-/**932932- * zfcp_adapter_debug_register - registers debug feature for an adapter933933- * @adapter: pointer to adapter for which debug features should be registered934934- * return: -ENOMEM on error, 0 otherwise935935- */936936-int937937-zfcp_adapter_debug_register(struct zfcp_adapter *adapter)938938-{939939- char dbf_name[20];940940-941941- /* debug feature area which records SCSI command failures (hostbyte) */942942- spin_lock_init(&adapter->dbf_lock);943943-944944- sprintf(dbf_name, ZFCP_CMD_DBF_NAME "%s",945945- zfcp_get_busid_by_adapter(adapter));946946- adapter->cmd_dbf = debug_register(dbf_name, ZFCP_CMD_DBF_INDEX,947947- ZFCP_CMD_DBF_AREAS,948948- ZFCP_CMD_DBF_LENGTH);949949- debug_register_view(adapter->cmd_dbf, &debug_hex_ascii_view);950950- debug_set_level(adapter->cmd_dbf, ZFCP_CMD_DBF_LEVEL);951951-952952- /* debug feature area which records SCSI command aborts */953953- sprintf(dbf_name, ZFCP_ABORT_DBF_NAME "%s",954954- zfcp_get_busid_by_adapter(adapter));955955- adapter->abort_dbf = debug_register(dbf_name, ZFCP_ABORT_DBF_INDEX,956956- ZFCP_ABORT_DBF_AREAS,957957- ZFCP_ABORT_DBF_LENGTH);958958- debug_register_view(adapter->abort_dbf, &debug_hex_ascii_view);959959- debug_set_level(adapter->abort_dbf, ZFCP_ABORT_DBF_LEVEL);960960-961961- /* debug feature area which records incoming ELS commands */962962- sprintf(dbf_name, ZFCP_IN_ELS_DBF_NAME "%s",963963- zfcp_get_busid_by_adapter(adapter));964964- adapter->in_els_dbf = debug_register(dbf_name, ZFCP_IN_ELS_DBF_INDEX,965965- ZFCP_IN_ELS_DBF_AREAS,966966- ZFCP_IN_ELS_DBF_LENGTH);967967- debug_register_view(adapter->in_els_dbf, &debug_hex_ascii_view);968968- debug_set_level(adapter->in_els_dbf, ZFCP_IN_ELS_DBF_LEVEL);969969-970970- /* debug feature area which records erp events */971971- sprintf(dbf_name, ZFCP_ERP_DBF_NAME "%s",972972- zfcp_get_busid_by_adapter(adapter));973973- adapter->erp_dbf = debug_register(dbf_name, ZFCP_ERP_DBF_INDEX,974974- ZFCP_ERP_DBF_AREAS,975975- ZFCP_ERP_DBF_LENGTH);976976- debug_register_view(adapter->erp_dbf, &debug_hex_ascii_view);977977- debug_set_level(adapter->erp_dbf, ZFCP_ERP_DBF_LEVEL);978978-979979- if (!(adapter->cmd_dbf && adapter->abort_dbf &&980980- adapter->in_els_dbf && adapter->erp_dbf)) {981981- zfcp_adapter_debug_unregister(adapter);982982- return -ENOMEM;983983- }984984-985985- return 0;986986-987987-}988988-989989-/**990990- * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter991991- * @adapter: pointer to adapter for which debug features should be unregistered992992- */993993-void994994-zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter)995995-{996996- debug_unregister(adapter->abort_dbf);997997- debug_unregister(adapter->cmd_dbf);998998- debug_unregister(adapter->erp_dbf);999999- debug_unregister(adapter->in_els_dbf);10001000- adapter->abort_dbf = NULL;10011001- adapter->cmd_dbf = NULL;10021002- adapter->erp_dbf = NULL;10031003- adapter->in_els_dbf = NULL;10041004-}10051005-10061020void10071021zfcp_dummy_release(struct device *dev)10081022{···12981462 /* see FC-FS */12991463 no_entries = (fcp_rscn_head->payload_len / 4);1300146413011301- zfcp_in_els_dbf_event(adapter, "##rscn", status_buffer,13021302- fcp_rscn_head->payload_len);13031303-13041304- debug_text_event(adapter->erp_dbf, 1, "unsol_els_rscn:");13051465 for (i = 1; i < no_entries; i++) {13061466 /* skip head and start with 1st element */13071467 fcp_rscn_element++;···13291497 (ZFCP_STATUS_PORT_DID_DID, &port->status)) {13301498 ZFCP_LOG_INFO("incoming RSCN, trying to open "13311499 "port 0x%016Lx\n", port->wwpn);13321332- debug_text_event(adapter->erp_dbf, 1,13331333- "unsol_els_rscnu:");13341500 zfcp_erp_port_reopen(port,13351501 ZFCP_STATUS_COMMON_ERP_FAILED);13361502 continue;···13541524 */13551525 ZFCP_LOG_INFO("incoming RSCN, trying to open "13561526 "port 0x%016Lx\n", port->wwpn);13571357- debug_text_event(adapter->erp_dbf, 1,13581358- "unsol_els_rscnk:");13591527 zfcp_test_link(port);13601528 }13611529 }···13691541 struct zfcp_port *port;13701542 unsigned long flags;1371154313721372- zfcp_in_els_dbf_event(adapter, "##plogi", status_buffer, 28);13731373-13741544 read_lock_irqsave(&zfcp_data.config_lock, flags);13751545 list_for_each_entry(port, &adapter->port_list_head, list) {13761546 if (port->wwpn == (*(wwn_t *) & els_logi->nport_wwn))···13821556 status_buffer->d_id,13831557 zfcp_get_busid_by_adapter(adapter));13841558 } else {13851385- debug_text_event(adapter->erp_dbf, 1, "unsol_els_plogi:");13861386- debug_event(adapter->erp_dbf, 1, &els_logi->nport_wwn, 8);13871559 zfcp_erp_port_forced_reopen(port, 0);13881560 }13891561}···13931569 struct fcp_logo *els_logo = (struct fcp_logo *) status_buffer->payload;13941570 struct zfcp_port *port;13951571 unsigned long flags;13961396-13971397- zfcp_in_els_dbf_event(adapter, "##logo", status_buffer, 16);1398157213991573 read_lock_irqsave(&zfcp_data.config_lock, flags);14001574 list_for_each_entry(port, &adapter->port_list_head, list) {···14071585 status_buffer->d_id,14081586 zfcp_get_busid_by_adapter(adapter));14091587 } else {14101410- debug_text_event(adapter->erp_dbf, 1, "unsol_els_logo:");14111411- debug_event(adapter->erp_dbf, 1, &els_logo->nport_wwpn, 8);14121588 zfcp_erp_port_forced_reopen(port, 0);14131589 }14141590}···14151595zfcp_fsf_incoming_els_unknown(struct zfcp_adapter *adapter,14161596 struct fsf_status_read_buffer *status_buffer)14171597{14181418- zfcp_in_els_dbf_event(adapter, "##undef", status_buffer, 24);14191598 ZFCP_LOG_NORMAL("warning: unknown incoming ELS 0x%08x "14201599 "for adapter %s\n", *(u32 *) (status_buffer->payload),14211600 zfcp_get_busid_by_adapter(adapter));···14281609 u32 els_type;14291610 struct zfcp_adapter *adapter;1430161114311431- status_buffer = fsf_req->data.status_read.buffer;16121612+ status_buffer = (struct fsf_status_read_buffer *) fsf_req->data;14321613 els_type = *(u32 *) (status_buffer->payload);14331614 adapter = fsf_req->adapter;1434161516161616+ zfcp_san_dbf_event_incoming_els(fsf_req);14351617 if (els_type == LS_PLOGI)14361618 zfcp_fsf_incoming_els_plogi(adapter, status_buffer);14371619 else if (els_type == LS_LOGO)
-10
drivers/s390/scsi/zfcp_ccw.c
···202202zfcp_ccw_set_offline(struct ccw_device *ccw_device)203203{204204 struct zfcp_adapter *adapter;205205- struct zfcp_port *port;206206- struct fc_rport *rport;207205208206 down(&zfcp_data.config_sema);209207 adapter = dev_get_drvdata(&ccw_device->dev);210210- /* might be racy, but we cannot take config_lock due to the fact that211211- fc_remote_port_delete might sleep */212212- list_for_each_entry(port, &adapter->port_list_head, list)213213- if (port->rport) {214214- rport = port->rport;215215- port->rport = NULL;216216- fc_remote_port_delete(rport);217217- }218208 zfcp_erp_adapter_shutdown(adapter, 0);219209 zfcp_erp_wait(adapter);220210 zfcp_adapter_scsi_unregister(adapter);
+995
drivers/s390/scsi/zfcp_dbf.c
···11+/*22+ *33+ * linux/drivers/s390/scsi/zfcp_dbf.c44+ *55+ * FCP adapter driver for IBM eServer zSeries66+ *77+ * Debugging facilities88+ *99+ * (C) Copyright IBM Corp. 20051010+ *1111+ * This program is free software; you can redistribute it and/or modify1212+ * it under the terms of the GNU General Public License as published by1313+ * the Free Software Foundation; either version 2, or (at your option)1414+ * any later version.1515+ *1616+ * This program is distributed in the hope that it will be useful,1717+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1818+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1919+ * GNU General Public License for more details.2020+ *2121+ * You should have received a copy of the GNU General Public License2222+ * along with this program; if not, write to the Free Software2323+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.2424+ */2525+2626+#define ZFCP_DBF_REVISION "$Revision$"2727+2828+#include <asm/debug.h>2929+#include <linux/ctype.h>3030+#include "zfcp_ext.h"3131+3232+static u32 dbfsize = 4;3333+3434+module_param(dbfsize, uint, 0400);3535+MODULE_PARM_DESC(dbfsize,3636+ "number of pages for each debug feature area (default 4)");3737+3838+#define ZFCP_LOG_AREA ZFCP_LOG_AREA_OTHER3939+4040+static inline int4141+zfcp_dbf_stck(char *out_buf, const char *label, unsigned long long stck)4242+{4343+ unsigned long long sec;4444+ struct timespec xtime;4545+ int len = 0;4646+4747+ stck -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096);4848+ sec = stck >> 12;4949+ do_div(sec, 1000000);5050+ xtime.tv_sec = sec;5151+ stck -= (sec * 1000000) << 12;5252+ xtime.tv_nsec = ((stck * 1000) >> 12);5353+ len += sprintf(out_buf + len, "%-24s%011lu:%06lu\n",5454+ label, xtime.tv_sec, xtime.tv_nsec);5555+5656+ return len;5757+}5858+5959+static int zfcp_dbf_tag(char *out_buf, const char *label, const char *tag)6060+{6161+ int len = 0, i;6262+6363+ len += sprintf(out_buf + len, "%-24s", label);6464+ for (i = 0; i < ZFCP_DBF_TAG_SIZE; i++)6565+ len += sprintf(out_buf + len, "%c", tag[i]);6666+ len += sprintf(out_buf + len, "\n");6767+6868+ return len;6969+}7070+7171+static int7272+zfcp_dbf_view(char *out_buf, const char *label, const char *format, ...)7373+{7474+ va_list arg;7575+ int len = 0;7676+7777+ len += sprintf(out_buf + len, "%-24s", label);7878+ va_start(arg, format);7979+ len += vsprintf(out_buf + len, format, arg);8080+ va_end(arg);8181+ len += sprintf(out_buf + len, "\n");8282+8383+ return len;8484+}8585+8686+static int8787+zfcp_dbf_view_dump(char *out_buf, const char *label,8888+ char *buffer, int buflen, int offset, int total_size)8989+{9090+ int len = 0;9191+9292+ if (offset == 0)9393+ len += sprintf(out_buf + len, "%-24s ", label);9494+9595+ while (buflen--) {9696+ if (offset > 0) {9797+ if ((offset % 32) == 0)9898+ len += sprintf(out_buf + len, "\n%-24c ", ' ');9999+ else if ((offset % 4) == 0)100100+ len += sprintf(out_buf + len, " ");101101+ }102102+ len += sprintf(out_buf + len, "%02x", *buffer++);103103+ if (++offset == total_size) {104104+ len += sprintf(out_buf + len, "\n");105105+ break;106106+ }107107+ }108108+109109+ if (total_size == 0)110110+ len += sprintf(out_buf + len, "\n");111111+112112+ return len;113113+}114114+115115+static inline int116116+zfcp_dbf_view_header(debug_info_t * id, struct debug_view *view, int area,117117+ debug_entry_t * entry, char *out_buf)118118+{119119+ struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)DEBUG_DATA(entry);120120+ int len = 0;121121+122122+ if (strncmp(dump->tag, "dump", ZFCP_DBF_TAG_SIZE) != 0) {123123+ len += zfcp_dbf_stck(out_buf + len, "timestamp",124124+ entry->id.stck);125125+ len += zfcp_dbf_view(out_buf + len, "cpu", "%02i",126126+ entry->id.fields.cpuid);127127+ } else {128128+ len += zfcp_dbf_view_dump(out_buf + len, NULL,129129+ dump->data,130130+ dump->size,131131+ dump->offset, dump->total_size);132132+ if ((dump->offset + dump->size) == dump->total_size)133133+ len += sprintf(out_buf + len, "\n");134134+ }135135+136136+ return len;137137+}138138+139139+inline void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)140140+{141141+ struct zfcp_adapter *adapter = fsf_req->adapter;142142+ struct fsf_qtcb *qtcb = fsf_req->qtcb;143143+ union fsf_prot_status_qual *prot_status_qual =144144+ &qtcb->prefix.prot_status_qual;145145+ union fsf_status_qual *fsf_status_qual = &qtcb->header.fsf_status_qual;146146+ struct scsi_cmnd *scsi_cmnd;147147+ struct zfcp_port *port;148148+ struct zfcp_unit *unit;149149+ struct zfcp_send_els *send_els;150150+ struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;151151+ struct zfcp_hba_dbf_record_response *response = &rec->type.response;152152+ int level;153153+ unsigned long flags;154154+155155+ spin_lock_irqsave(&adapter->hba_dbf_lock, flags);156156+ memset(rec, 0, sizeof(struct zfcp_hba_dbf_record));157157+ strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE);158158+159159+ if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&160160+ (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) {161161+ strncpy(rec->tag2, "perr", ZFCP_DBF_TAG_SIZE);162162+ level = 1;163163+ } else if (qtcb->header.fsf_status != FSF_GOOD) {164164+ strncpy(rec->tag2, "ferr", ZFCP_DBF_TAG_SIZE);165165+ level = 1;166166+ } else if ((fsf_req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) ||167167+ (fsf_req->fsf_command == FSF_QTCB_OPEN_LUN)) {168168+ strncpy(rec->tag2, "open", ZFCP_DBF_TAG_SIZE);169169+ level = 4;170170+ } else if ((prot_status_qual->doubleword[0] != 0) ||171171+ (prot_status_qual->doubleword[1] != 0) ||172172+ (fsf_status_qual->doubleword[0] != 0) ||173173+ (fsf_status_qual->doubleword[1] != 0)) {174174+ strncpy(rec->tag2, "qual", ZFCP_DBF_TAG_SIZE);175175+ level = 3;176176+ } else {177177+ strncpy(rec->tag2, "norm", ZFCP_DBF_TAG_SIZE);178178+ level = 6;179179+ }180180+181181+ response->fsf_command = fsf_req->fsf_command;182182+ response->fsf_reqid = (unsigned long)fsf_req;183183+ response->fsf_seqno = fsf_req->seq_no;184184+ response->fsf_issued = fsf_req->issued;185185+ response->fsf_prot_status = qtcb->prefix.prot_status;186186+ response->fsf_status = qtcb->header.fsf_status;187187+ memcpy(response->fsf_prot_status_qual,188188+ prot_status_qual, FSF_PROT_STATUS_QUAL_SIZE);189189+ memcpy(response->fsf_status_qual,190190+ fsf_status_qual, FSF_STATUS_QUALIFIER_SIZE);191191+ response->fsf_req_status = fsf_req->status;192192+ response->sbal_first = fsf_req->sbal_first;193193+ response->sbal_curr = fsf_req->sbal_curr;194194+ response->sbal_last = fsf_req->sbal_last;195195+ response->pool = fsf_req->pool != NULL;196196+ response->erp_action = (unsigned long)fsf_req->erp_action;197197+198198+ switch (fsf_req->fsf_command) {199199+ case FSF_QTCB_FCP_CMND:200200+ if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)201201+ break;202202+ scsi_cmnd = (struct scsi_cmnd *)fsf_req->data;203203+ if (scsi_cmnd != NULL) {204204+ response->data.send_fcp.scsi_cmnd205205+ = (unsigned long)scsi_cmnd;206206+ response->data.send_fcp.scsi_serial207207+ = scsi_cmnd->serial_number;208208+ }209209+ break;210210+211211+ case FSF_QTCB_OPEN_PORT_WITH_DID:212212+ case FSF_QTCB_CLOSE_PORT:213213+ case FSF_QTCB_CLOSE_PHYSICAL_PORT:214214+ port = (struct zfcp_port *)fsf_req->data;215215+ response->data.port.wwpn = port->wwpn;216216+ response->data.port.d_id = port->d_id;217217+ response->data.port.port_handle = qtcb->header.port_handle;218218+ break;219219+220220+ case FSF_QTCB_OPEN_LUN:221221+ case FSF_QTCB_CLOSE_LUN:222222+ unit = (struct zfcp_unit *)fsf_req->data;223223+ port = unit->port;224224+ response->data.unit.wwpn = port->wwpn;225225+ response->data.unit.fcp_lun = unit->fcp_lun;226226+ response->data.unit.port_handle = qtcb->header.port_handle;227227+ response->data.unit.lun_handle = qtcb->header.lun_handle;228228+ break;229229+230230+ case FSF_QTCB_SEND_ELS:231231+ send_els = (struct zfcp_send_els *)fsf_req->data;232232+ response->data.send_els.d_id = qtcb->bottom.support.d_id;233233+ response->data.send_els.ls_code = send_els->ls_code >> 24;234234+ break;235235+236236+ case FSF_QTCB_ABORT_FCP_CMND:237237+ case FSF_QTCB_SEND_GENERIC:238238+ case FSF_QTCB_EXCHANGE_CONFIG_DATA:239239+ case FSF_QTCB_EXCHANGE_PORT_DATA:240240+ case FSF_QTCB_DOWNLOAD_CONTROL_FILE:241241+ case FSF_QTCB_UPLOAD_CONTROL_FILE:242242+ break;243243+ }244244+245245+ debug_event(adapter->hba_dbf, level,246246+ rec, sizeof(struct zfcp_hba_dbf_record));247247+ spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);248248+}249249+250250+inline void251251+zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter,252252+ struct fsf_status_read_buffer *status_buffer)253253+{254254+ struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;255255+ unsigned long flags;256256+257257+ spin_lock_irqsave(&adapter->hba_dbf_lock, flags);258258+ memset(rec, 0, sizeof(struct zfcp_hba_dbf_record));259259+ strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE);260260+ strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE);261261+262262+ rec->type.status.failed = adapter->status_read_failed;263263+ if (status_buffer != NULL) {264264+ rec->type.status.status_type = status_buffer->status_type;265265+ rec->type.status.status_subtype = status_buffer->status_subtype;266266+ memcpy(&rec->type.status.queue_designator,267267+ &status_buffer->queue_designator,268268+ sizeof(struct fsf_queue_designator));269269+270270+ switch (status_buffer->status_type) {271271+ case FSF_STATUS_READ_SENSE_DATA_AVAIL:272272+ rec->type.status.payload_size =273273+ ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL;274274+ break;275275+276276+ case FSF_STATUS_READ_BIT_ERROR_THRESHOLD:277277+ rec->type.status.payload_size =278278+ ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD;279279+ break;280280+281281+ case FSF_STATUS_READ_LINK_DOWN:282282+ switch (status_buffer->status_subtype) {283283+ case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:284284+ case FSF_STATUS_READ_SUB_FDISC_FAILED:285285+ rec->type.status.payload_size =286286+ sizeof(struct fsf_link_down_info);287287+ }288288+ break;289289+290290+ case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:291291+ rec->type.status.payload_size =292292+ ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT;293293+ break;294294+ }295295+ memcpy(&rec->type.status.payload,296296+ &status_buffer->payload, rec->type.status.payload_size);297297+ }298298+299299+ debug_event(adapter->hba_dbf, 2,300300+ rec, sizeof(struct zfcp_hba_dbf_record));301301+ spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);302302+}303303+304304+inline void305305+zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status,306306+ unsigned int qdio_error, unsigned int siga_error,307307+ int sbal_index, int sbal_count)308308+{309309+ struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;310310+ unsigned long flags;311311+312312+ spin_lock_irqsave(&adapter->hba_dbf_lock, flags);313313+ memset(rec, 0, sizeof(struct zfcp_hba_dbf_record));314314+ strncpy(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE);315315+ rec->type.qdio.status = status;316316+ rec->type.qdio.qdio_error = qdio_error;317317+ rec->type.qdio.siga_error = siga_error;318318+ rec->type.qdio.sbal_index = sbal_index;319319+ rec->type.qdio.sbal_count = sbal_count;320320+ debug_event(adapter->hba_dbf, 0,321321+ rec, sizeof(struct zfcp_hba_dbf_record));322322+ spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);323323+}324324+325325+static inline int326326+zfcp_hba_dbf_view_response(char *out_buf,327327+ struct zfcp_hba_dbf_record_response *rec)328328+{329329+ int len = 0;330330+331331+ len += zfcp_dbf_view(out_buf + len, "fsf_command", "0x%08x",332332+ rec->fsf_command);333333+ len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx",334334+ rec->fsf_reqid);335335+ len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x",336336+ rec->fsf_seqno);337337+ len += zfcp_dbf_stck(out_buf + len, "fsf_issued", rec->fsf_issued);338338+ len += zfcp_dbf_view(out_buf + len, "fsf_prot_status", "0x%08x",339339+ rec->fsf_prot_status);340340+ len += zfcp_dbf_view(out_buf + len, "fsf_status", "0x%08x",341341+ rec->fsf_status);342342+ len += zfcp_dbf_view_dump(out_buf + len, "fsf_prot_status_qual",343343+ rec->fsf_prot_status_qual,344344+ FSF_PROT_STATUS_QUAL_SIZE,345345+ 0, FSF_PROT_STATUS_QUAL_SIZE);346346+ len += zfcp_dbf_view_dump(out_buf + len, "fsf_status_qual",347347+ rec->fsf_status_qual,348348+ FSF_STATUS_QUALIFIER_SIZE,349349+ 0, FSF_STATUS_QUALIFIER_SIZE);350350+ len += zfcp_dbf_view(out_buf + len, "fsf_req_status", "0x%08x",351351+ rec->fsf_req_status);352352+ len += zfcp_dbf_view(out_buf + len, "sbal_first", "0x%02x",353353+ rec->sbal_first);354354+ len += zfcp_dbf_view(out_buf + len, "sbal_curr", "0x%02x",355355+ rec->sbal_curr);356356+ len += zfcp_dbf_view(out_buf + len, "sbal_last", "0x%02x",357357+ rec->sbal_last);358358+ len += zfcp_dbf_view(out_buf + len, "pool", "0x%02x", rec->pool);359359+360360+ switch (rec->fsf_command) {361361+ case FSF_QTCB_FCP_CMND:362362+ if (rec->fsf_req_status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)363363+ break;364364+ len += zfcp_dbf_view(out_buf + len, "scsi_cmnd", "0x%0Lx",365365+ rec->data.send_fcp.scsi_cmnd);366366+ len += zfcp_dbf_view(out_buf + len, "scsi_serial", "0x%016Lx",367367+ rec->data.send_fcp.scsi_serial);368368+ break;369369+370370+ case FSF_QTCB_OPEN_PORT_WITH_DID:371371+ case FSF_QTCB_CLOSE_PORT:372372+ case FSF_QTCB_CLOSE_PHYSICAL_PORT:373373+ len += zfcp_dbf_view(out_buf + len, "wwpn", "0x%016Lx",374374+ rec->data.port.wwpn);375375+ len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x",376376+ rec->data.port.d_id);377377+ len += zfcp_dbf_view(out_buf + len, "port_handle", "0x%08x",378378+ rec->data.port.port_handle);379379+ break;380380+381381+ case FSF_QTCB_OPEN_LUN:382382+ case FSF_QTCB_CLOSE_LUN:383383+ len += zfcp_dbf_view(out_buf + len, "wwpn", "0x%016Lx",384384+ rec->data.unit.wwpn);385385+ len += zfcp_dbf_view(out_buf + len, "fcp_lun", "0x%016Lx",386386+ rec->data.unit.fcp_lun);387387+ len += zfcp_dbf_view(out_buf + len, "port_handle", "0x%08x",388388+ rec->data.unit.port_handle);389389+ len += zfcp_dbf_view(out_buf + len, "lun_handle", "0x%08x",390390+ rec->data.unit.lun_handle);391391+ break;392392+393393+ case FSF_QTCB_SEND_ELS:394394+ len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x",395395+ rec->data.send_els.d_id);396396+ len += zfcp_dbf_view(out_buf + len, "ls_code", "0x%02x",397397+ rec->data.send_els.ls_code);398398+ break;399399+400400+ case FSF_QTCB_ABORT_FCP_CMND:401401+ case FSF_QTCB_SEND_GENERIC:402402+ case FSF_QTCB_EXCHANGE_CONFIG_DATA:403403+ case FSF_QTCB_EXCHANGE_PORT_DATA:404404+ case FSF_QTCB_DOWNLOAD_CONTROL_FILE:405405+ case FSF_QTCB_UPLOAD_CONTROL_FILE:406406+ break;407407+ }408408+409409+ return len;410410+}411411+412412+static inline int413413+zfcp_hba_dbf_view_status(char *out_buf, struct zfcp_hba_dbf_record_status *rec)414414+{415415+ int len = 0;416416+417417+ len += zfcp_dbf_view(out_buf + len, "failed", "0x%02x", rec->failed);418418+ len += zfcp_dbf_view(out_buf + len, "status_type", "0x%08x",419419+ rec->status_type);420420+ len += zfcp_dbf_view(out_buf + len, "status_subtype", "0x%08x",421421+ rec->status_subtype);422422+ len += zfcp_dbf_view_dump(out_buf + len, "queue_designator",423423+ (char *)&rec->queue_designator,424424+ sizeof(struct fsf_queue_designator),425425+ 0, sizeof(struct fsf_queue_designator));426426+ len += zfcp_dbf_view_dump(out_buf + len, "payload",427427+ (char *)&rec->payload,428428+ rec->payload_size, 0, rec->payload_size);429429+430430+ return len;431431+}432432+433433+static inline int434434+zfcp_hba_dbf_view_qdio(char *out_buf, struct zfcp_hba_dbf_record_qdio *rec)435435+{436436+ int len = 0;437437+438438+ len += zfcp_dbf_view(out_buf + len, "status", "0x%08x", rec->status);439439+ len += zfcp_dbf_view(out_buf + len, "qdio_error", "0x%08x",440440+ rec->qdio_error);441441+ len += zfcp_dbf_view(out_buf + len, "siga_error", "0x%08x",442442+ rec->siga_error);443443+ len += zfcp_dbf_view(out_buf + len, "sbal_index", "0x%02x",444444+ rec->sbal_index);445445+ len += zfcp_dbf_view(out_buf + len, "sbal_count", "0x%02x",446446+ rec->sbal_count);447447+448448+ return len;449449+}450450+451451+static int452452+zfcp_hba_dbf_view_format(debug_info_t * id, struct debug_view *view,453453+ char *out_buf, const char *in_buf)454454+{455455+ struct zfcp_hba_dbf_record *rec = (struct zfcp_hba_dbf_record *)in_buf;456456+ int len = 0;457457+458458+ if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)459459+ return 0;460460+461461+ len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag);462462+ if (isalpha(rec->tag2[0]))463463+ len += zfcp_dbf_tag(out_buf + len, "tag2", rec->tag2);464464+ if (strncmp(rec->tag, "resp", ZFCP_DBF_TAG_SIZE) == 0)465465+ len += zfcp_hba_dbf_view_response(out_buf + len,466466+ &rec->type.response);467467+ else if (strncmp(rec->tag, "stat", ZFCP_DBF_TAG_SIZE) == 0)468468+ len += zfcp_hba_dbf_view_status(out_buf + len,469469+ &rec->type.status);470470+ else if (strncmp(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0)471471+ len += zfcp_hba_dbf_view_qdio(out_buf + len, &rec->type.qdio);472472+473473+ len += sprintf(out_buf + len, "\n");474474+475475+ return len;476476+}477477+478478+struct debug_view zfcp_hba_dbf_view = {479479+ "structured",480480+ NULL,481481+ &zfcp_dbf_view_header,482482+ &zfcp_hba_dbf_view_format,483483+ NULL,484484+ NULL485485+};486486+487487+inline void488488+_zfcp_san_dbf_event_common_ct(const char *tag, struct zfcp_fsf_req *fsf_req,489489+ u32 s_id, u32 d_id, void *buffer, int buflen)490490+{491491+ struct zfcp_send_ct *send_ct = (struct zfcp_send_ct *)fsf_req->data;492492+ struct zfcp_port *port = send_ct->port;493493+ struct zfcp_adapter *adapter = port->adapter;494494+ struct ct_hdr *header = (struct ct_hdr *)buffer;495495+ struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf;496496+ struct zfcp_san_dbf_record_ct *ct = &rec->type.ct;497497+ unsigned long flags;498498+499499+ spin_lock_irqsave(&adapter->san_dbf_lock, flags);500500+ memset(rec, 0, sizeof(struct zfcp_san_dbf_record));501501+ strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);502502+ rec->fsf_reqid = (unsigned long)fsf_req;503503+ rec->fsf_seqno = fsf_req->seq_no;504504+ rec->s_id = s_id;505505+ rec->d_id = d_id;506506+ if (strncmp(tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) {507507+ ct->type.request.cmd_req_code = header->cmd_rsp_code;508508+ ct->type.request.revision = header->revision;509509+ ct->type.request.gs_type = header->gs_type;510510+ ct->type.request.gs_subtype = header->gs_subtype;511511+ ct->type.request.options = header->options;512512+ ct->type.request.max_res_size = header->max_res_size;513513+ } else if (strncmp(tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) {514514+ ct->type.response.cmd_rsp_code = header->cmd_rsp_code;515515+ ct->type.response.revision = header->revision;516516+ ct->type.response.reason_code = header->reason_code;517517+ ct->type.response.reason_code_expl = header->reason_code_expl;518518+ ct->type.response.vendor_unique = header->vendor_unique;519519+ }520520+ ct->payload_size =521521+ min(buflen - (int)sizeof(struct ct_hdr), ZFCP_DBF_CT_PAYLOAD);522522+ memcpy(ct->payload, buffer + sizeof(struct ct_hdr), ct->payload_size);523523+ debug_event(adapter->san_dbf, 3,524524+ rec, sizeof(struct zfcp_san_dbf_record));525525+ spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);526526+}527527+528528+inline void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)529529+{530530+ struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;531531+ struct zfcp_port *port = ct->port;532532+ struct zfcp_adapter *adapter = port->adapter;533533+534534+ _zfcp_san_dbf_event_common_ct("octc", fsf_req,535535+ fc_host_port_id(adapter->scsi_host),536536+ port->d_id, zfcp_sg_to_address(ct->req),537537+ ct->req->length);538538+}539539+540540+inline void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)541541+{542542+ struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;543543+ struct zfcp_port *port = ct->port;544544+ struct zfcp_adapter *adapter = port->adapter;545545+546546+ _zfcp_san_dbf_event_common_ct("rctc", fsf_req, port->d_id,547547+ fc_host_port_id(adapter->scsi_host),548548+ zfcp_sg_to_address(ct->resp),549549+ ct->resp->length);550550+}551551+552552+static inline void553553+_zfcp_san_dbf_event_common_els(const char *tag, int level,554554+ struct zfcp_fsf_req *fsf_req, u32 s_id,555555+ u32 d_id, u8 ls_code, void *buffer, int buflen)556556+{557557+ struct zfcp_adapter *adapter = fsf_req->adapter;558558+ struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf;559559+ struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;560560+ unsigned long flags;561561+ int offset = 0;562562+563563+ spin_lock_irqsave(&adapter->san_dbf_lock, flags);564564+ do {565565+ memset(rec, 0, sizeof(struct zfcp_san_dbf_record));566566+ if (offset == 0) {567567+ strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);568568+ rec->fsf_reqid = (unsigned long)fsf_req;569569+ rec->fsf_seqno = fsf_req->seq_no;570570+ rec->s_id = s_id;571571+ rec->d_id = d_id;572572+ rec->type.els.ls_code = ls_code;573573+ buflen = min(buflen, ZFCP_DBF_ELS_MAX_PAYLOAD);574574+ rec->type.els.payload_size = buflen;575575+ memcpy(rec->type.els.payload,576576+ buffer, min(buflen, ZFCP_DBF_ELS_PAYLOAD));577577+ offset += min(buflen, ZFCP_DBF_ELS_PAYLOAD);578578+ } else {579579+ strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);580580+ dump->total_size = buflen;581581+ dump->offset = offset;582582+ dump->size = min(buflen - offset,583583+ (int)sizeof(struct zfcp_san_dbf_record)584584+ - (int)sizeof(struct zfcp_dbf_dump));585585+ memcpy(dump->data, buffer + offset, dump->size);586586+ offset += dump->size;587587+ }588588+ debug_event(adapter->san_dbf, level,589589+ rec, sizeof(struct zfcp_san_dbf_record));590590+ } while (offset < buflen);591591+ spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);592592+}593593+594594+inline void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req)595595+{596596+ struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;597597+598598+ _zfcp_san_dbf_event_common_els("oels", 2, fsf_req,599599+ fc_host_port_id(els->adapter->scsi_host),600600+ els->d_id,601601+ *(u8 *) zfcp_sg_to_address(els->req),602602+ zfcp_sg_to_address(els->req),603603+ els->req->length);604604+}605605+606606+inline void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req)607607+{608608+ struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;609609+610610+ _zfcp_san_dbf_event_common_els("rels", 2, fsf_req, els->d_id,611611+ fc_host_port_id(els->adapter->scsi_host),612612+ *(u8 *) zfcp_sg_to_address(els->req),613613+ zfcp_sg_to_address(els->resp),614614+ els->resp->length);615615+}616616+617617+inline void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req)618618+{619619+ struct zfcp_adapter *adapter = fsf_req->adapter;620620+ struct fsf_status_read_buffer *status_buffer =621621+ (struct fsf_status_read_buffer *)fsf_req->data;622622+ int length = (int)status_buffer->length -623623+ (int)((void *)&status_buffer->payload - (void *)status_buffer);624624+625625+ _zfcp_san_dbf_event_common_els("iels", 1, fsf_req, status_buffer->d_id,626626+ fc_host_port_id(adapter->scsi_host),627627+ *(u8 *) status_buffer->payload,628628+ (void *)status_buffer->payload, length);629629+}630630+631631+static int632632+zfcp_san_dbf_view_format(debug_info_t * id, struct debug_view *view,633633+ char *out_buf, const char *in_buf)634634+{635635+ struct zfcp_san_dbf_record *rec = (struct zfcp_san_dbf_record *)in_buf;636636+ char *buffer = NULL;637637+ int buflen = 0, total = 0;638638+ int len = 0;639639+640640+ if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)641641+ return 0;642642+643643+ len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag);644644+ len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx",645645+ rec->fsf_reqid);646646+ len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x",647647+ rec->fsf_seqno);648648+ len += zfcp_dbf_view(out_buf + len, "s_id", "0x%06x", rec->s_id);649649+ len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x", rec->d_id);650650+651651+ if (strncmp(rec->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) {652652+ len += zfcp_dbf_view(out_buf + len, "cmd_req_code", "0x%04x",653653+ rec->type.ct.type.request.cmd_req_code);654654+ len += zfcp_dbf_view(out_buf + len, "revision", "0x%02x",655655+ rec->type.ct.type.request.revision);656656+ len += zfcp_dbf_view(out_buf + len, "gs_type", "0x%02x",657657+ rec->type.ct.type.request.gs_type);658658+ len += zfcp_dbf_view(out_buf + len, "gs_subtype", "0x%02x",659659+ rec->type.ct.type.request.gs_subtype);660660+ len += zfcp_dbf_view(out_buf + len, "options", "0x%02x",661661+ rec->type.ct.type.request.options);662662+ len += zfcp_dbf_view(out_buf + len, "max_res_size", "0x%04x",663663+ rec->type.ct.type.request.max_res_size);664664+ total = rec->type.ct.payload_size;665665+ buffer = rec->type.ct.payload;666666+ buflen = min(total, ZFCP_DBF_CT_PAYLOAD);667667+ } else if (strncmp(rec->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) {668668+ len += zfcp_dbf_view(out_buf + len, "cmd_rsp_code", "0x%04x",669669+ rec->type.ct.type.response.cmd_rsp_code);670670+ len += zfcp_dbf_view(out_buf + len, "revision", "0x%02x",671671+ rec->type.ct.type.response.revision);672672+ len += zfcp_dbf_view(out_buf + len, "reason_code", "0x%02x",673673+ rec->type.ct.type.response.reason_code);674674+ len +=675675+ zfcp_dbf_view(out_buf + len, "reason_code_expl", "0x%02x",676676+ rec->type.ct.type.response.reason_code_expl);677677+ len +=678678+ zfcp_dbf_view(out_buf + len, "vendor_unique", "0x%02x",679679+ rec->type.ct.type.response.vendor_unique);680680+ total = rec->type.ct.payload_size;681681+ buffer = rec->type.ct.payload;682682+ buflen = min(total, ZFCP_DBF_CT_PAYLOAD);683683+ } else if (strncmp(rec->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 ||684684+ strncmp(rec->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 ||685685+ strncmp(rec->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) {686686+ len += zfcp_dbf_view(out_buf + len, "ls_code", "0x%02x",687687+ rec->type.els.ls_code);688688+ total = rec->type.els.payload_size;689689+ buffer = rec->type.els.payload;690690+ buflen = min(total, ZFCP_DBF_ELS_PAYLOAD);691691+ }692692+693693+ len += zfcp_dbf_view_dump(out_buf + len, "payload",694694+ buffer, buflen, 0, total);695695+696696+ if (buflen == total)697697+ len += sprintf(out_buf + len, "\n");698698+699699+ return len;700700+}701701+702702+struct debug_view zfcp_san_dbf_view = {703703+ "structured",704704+ NULL,705705+ &zfcp_dbf_view_header,706706+ &zfcp_san_dbf_view_format,707707+ NULL,708708+ NULL709709+};710710+711711+static inline void712712+_zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,713713+ struct zfcp_adapter *adapter,714714+ struct scsi_cmnd *scsi_cmnd,715715+ struct zfcp_fsf_req *new_fsf_req)716716+{717717+ struct zfcp_fsf_req *fsf_req =718718+ (struct zfcp_fsf_req *)scsi_cmnd->host_scribble;719719+ struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf;720720+ struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;721721+ unsigned long flags;722722+ struct fcp_rsp_iu *fcp_rsp;723723+ char *fcp_rsp_info = NULL, *fcp_sns_info = NULL;724724+ int offset = 0, buflen = 0;725725+726726+ spin_lock_irqsave(&adapter->scsi_dbf_lock, flags);727727+ do {728728+ memset(rec, 0, sizeof(struct zfcp_scsi_dbf_record));729729+ if (offset == 0) {730730+ strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);731731+ strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE);732732+ if (scsi_cmnd->device) {733733+ rec->scsi_id = scsi_cmnd->device->id;734734+ rec->scsi_lun = scsi_cmnd->device->lun;735735+ }736736+ rec->scsi_result = scsi_cmnd->result;737737+ rec->scsi_cmnd = (unsigned long)scsi_cmnd;738738+ rec->scsi_serial = scsi_cmnd->serial_number;739739+ memcpy(rec->scsi_opcode,740740+ &scsi_cmnd->cmnd,741741+ min((int)scsi_cmnd->cmd_len,742742+ ZFCP_DBF_SCSI_OPCODE));743743+ rec->scsi_retries = scsi_cmnd->retries;744744+ rec->scsi_allowed = scsi_cmnd->allowed;745745+ if (fsf_req != NULL) {746746+ fcp_rsp = (struct fcp_rsp_iu *)747747+ &(fsf_req->qtcb->bottom.io.fcp_rsp);748748+ fcp_rsp_info =749749+ zfcp_get_fcp_rsp_info_ptr(fcp_rsp);750750+ fcp_sns_info =751751+ zfcp_get_fcp_sns_info_ptr(fcp_rsp);752752+753753+ rec->type.fcp.rsp_validity =754754+ fcp_rsp->validity.value;755755+ rec->type.fcp.rsp_scsi_status =756756+ fcp_rsp->scsi_status;757757+ rec->type.fcp.rsp_resid = fcp_rsp->fcp_resid;758758+ if (fcp_rsp->validity.bits.fcp_rsp_len_valid)759759+ rec->type.fcp.rsp_code =760760+ *(fcp_rsp_info + 3);761761+ if (fcp_rsp->validity.bits.fcp_sns_len_valid) {762762+ buflen = min((int)fcp_rsp->fcp_sns_len,763763+ ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO);764764+ rec->type.fcp.sns_info_len = buflen;765765+ memcpy(rec->type.fcp.sns_info,766766+ fcp_sns_info,767767+ min(buflen,768768+ ZFCP_DBF_SCSI_FCP_SNS_INFO));769769+ offset += min(buflen,770770+ ZFCP_DBF_SCSI_FCP_SNS_INFO);771771+ }772772+773773+ rec->fsf_reqid = (unsigned long)fsf_req;774774+ rec->fsf_seqno = fsf_req->seq_no;775775+ rec->fsf_issued = fsf_req->issued;776776+ }777777+ if (new_fsf_req != NULL) {778778+ rec->type.new_fsf_req.fsf_reqid =779779+ (unsigned long)780780+ new_fsf_req;781781+ rec->type.new_fsf_req.fsf_seqno =782782+ new_fsf_req->seq_no;783783+ rec->type.new_fsf_req.fsf_issued =784784+ new_fsf_req->issued;785785+ }786786+ } else {787787+ strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);788788+ dump->total_size = buflen;789789+ dump->offset = offset;790790+ dump->size = min(buflen - offset,791791+ (int)sizeof(struct792792+ zfcp_scsi_dbf_record) -793793+ (int)sizeof(struct zfcp_dbf_dump));794794+ memcpy(dump->data, fcp_sns_info + offset, dump->size);795795+ offset += dump->size;796796+ }797797+ debug_event(adapter->scsi_dbf, level,798798+ rec, sizeof(struct zfcp_scsi_dbf_record));799799+ } while (offset < buflen);800800+ spin_unlock_irqrestore(&adapter->scsi_dbf_lock, flags);801801+}802802+803803+inline void804804+zfcp_scsi_dbf_event_result(const char *tag, int level,805805+ struct zfcp_adapter *adapter,806806+ struct scsi_cmnd *scsi_cmnd)807807+{808808+ _zfcp_scsi_dbf_event_common("rslt",809809+ tag, level, adapter, scsi_cmnd, NULL);810810+}811811+812812+inline void813813+zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter,814814+ struct scsi_cmnd *scsi_cmnd,815815+ struct zfcp_fsf_req *new_fsf_req)816816+{817817+ _zfcp_scsi_dbf_event_common("abrt",818818+ tag, 1, adapter, scsi_cmnd, new_fsf_req);819819+}820820+821821+inline void822822+zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit,823823+ struct scsi_cmnd *scsi_cmnd)824824+{825825+ struct zfcp_adapter *adapter = unit->port->adapter;826826+827827+ _zfcp_scsi_dbf_event_common(flag == FCP_TARGET_RESET ? "trst" : "lrst",828828+ tag, 1, adapter, scsi_cmnd, NULL);829829+}830830+831831+static int832832+zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view,833833+ char *out_buf, const char *in_buf)834834+{835835+ struct zfcp_scsi_dbf_record *rec =836836+ (struct zfcp_scsi_dbf_record *)in_buf;837837+ int len = 0;838838+839839+ if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)840840+ return 0;841841+842842+ len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag);843843+ len += zfcp_dbf_tag(out_buf + len, "tag2", rec->tag2);844844+ len += zfcp_dbf_view(out_buf + len, "scsi_id", "0x%08x", rec->scsi_id);845845+ len += zfcp_dbf_view(out_buf + len, "scsi_lun", "0x%08x",846846+ rec->scsi_lun);847847+ len += zfcp_dbf_view(out_buf + len, "scsi_result", "0x%08x",848848+ rec->scsi_result);849849+ len += zfcp_dbf_view(out_buf + len, "scsi_cmnd", "0x%0Lx",850850+ rec->scsi_cmnd);851851+ len += zfcp_dbf_view(out_buf + len, "scsi_serial", "0x%016Lx",852852+ rec->scsi_serial);853853+ len += zfcp_dbf_view_dump(out_buf + len, "scsi_opcode",854854+ rec->scsi_opcode,855855+ ZFCP_DBF_SCSI_OPCODE,856856+ 0, ZFCP_DBF_SCSI_OPCODE);857857+ len += zfcp_dbf_view(out_buf + len, "scsi_retries", "0x%02x",858858+ rec->scsi_retries);859859+ len += zfcp_dbf_view(out_buf + len, "scsi_allowed", "0x%02x",860860+ rec->scsi_allowed);861861+ len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx",862862+ rec->fsf_reqid);863863+ len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x",864864+ rec->fsf_seqno);865865+ len += zfcp_dbf_stck(out_buf + len, "fsf_issued", rec->fsf_issued);866866+ if (strncmp(rec->tag, "rslt", ZFCP_DBF_TAG_SIZE) == 0) {867867+ len +=868868+ zfcp_dbf_view(out_buf + len, "fcp_rsp_validity", "0x%02x",869869+ rec->type.fcp.rsp_validity);870870+ len +=871871+ zfcp_dbf_view(out_buf + len, "fcp_rsp_scsi_status",872872+ "0x%02x", rec->type.fcp.rsp_scsi_status);873873+ len +=874874+ zfcp_dbf_view(out_buf + len, "fcp_rsp_resid", "0x%08x",875875+ rec->type.fcp.rsp_resid);876876+ len +=877877+ zfcp_dbf_view(out_buf + len, "fcp_rsp_code", "0x%08x",878878+ rec->type.fcp.rsp_code);879879+ len +=880880+ zfcp_dbf_view(out_buf + len, "fcp_sns_info_len", "0x%08x",881881+ rec->type.fcp.sns_info_len);882882+ len +=883883+ zfcp_dbf_view_dump(out_buf + len, "fcp_sns_info",884884+ rec->type.fcp.sns_info,885885+ min((int)rec->type.fcp.sns_info_len,886886+ ZFCP_DBF_SCSI_FCP_SNS_INFO), 0,887887+ rec->type.fcp.sns_info_len);888888+ } else if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) {889889+ len += zfcp_dbf_view(out_buf + len, "fsf_reqid_abort", "0x%0Lx",890890+ rec->type.new_fsf_req.fsf_reqid);891891+ len += zfcp_dbf_view(out_buf + len, "fsf_seqno_abort", "0x%08x",892892+ rec->type.new_fsf_req.fsf_seqno);893893+ len += zfcp_dbf_stck(out_buf + len, "fsf_issued",894894+ rec->type.new_fsf_req.fsf_issued);895895+ } else if ((strncmp(rec->tag, "trst", ZFCP_DBF_TAG_SIZE) == 0) ||896896+ (strncmp(rec->tag, "lrst", ZFCP_DBF_TAG_SIZE) == 0)) {897897+ len += zfcp_dbf_view(out_buf + len, "fsf_reqid_reset", "0x%0Lx",898898+ rec->type.new_fsf_req.fsf_reqid);899899+ len += zfcp_dbf_view(out_buf + len, "fsf_seqno_reset", "0x%08x",900900+ rec->type.new_fsf_req.fsf_seqno);901901+ len += zfcp_dbf_stck(out_buf + len, "fsf_issued",902902+ rec->type.new_fsf_req.fsf_issued);903903+ }904904+905905+ len += sprintf(out_buf + len, "\n");906906+907907+ return len;908908+}909909+910910+struct debug_view zfcp_scsi_dbf_view = {911911+ "structured",912912+ NULL,913913+ &zfcp_dbf_view_header,914914+ &zfcp_scsi_dbf_view_format,915915+ NULL,916916+ NULL917917+};918918+919919+/**920920+ * zfcp_adapter_debug_register - registers debug feature for an adapter921921+ * @adapter: pointer to adapter for which debug features should be registered922922+ * return: -ENOMEM on error, 0 otherwise923923+ */924924+int zfcp_adapter_debug_register(struct zfcp_adapter *adapter)925925+{926926+ char dbf_name[DEBUG_MAX_NAME_LEN];927927+928928+ /* debug feature area which records recovery activity */929929+ spin_lock_init(&adapter->erp_dbf_lock);930930+ sprintf(dbf_name, "zfcp_%s_erp", zfcp_get_busid_by_adapter(adapter));931931+ adapter->erp_dbf = debug_register(dbf_name, dbfsize, 2,932932+ sizeof(struct zfcp_erp_dbf_record));933933+ if (!adapter->erp_dbf)934934+ goto failed;935935+ debug_register_view(adapter->erp_dbf, &debug_hex_ascii_view);936936+ debug_set_level(adapter->erp_dbf, 3);937937+938938+ /* debug feature area which records HBA (FSF and QDIO) conditions */939939+ spin_lock_init(&adapter->hba_dbf_lock);940940+ sprintf(dbf_name, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter));941941+ adapter->hba_dbf = debug_register(dbf_name, dbfsize, 1,942942+ sizeof(struct zfcp_hba_dbf_record));943943+ if (!adapter->hba_dbf)944944+ goto failed;945945+ debug_register_view(adapter->hba_dbf, &debug_hex_ascii_view);946946+ debug_register_view(adapter->hba_dbf, &zfcp_hba_dbf_view);947947+ debug_set_level(adapter->hba_dbf, 3);948948+949949+ /* debug feature area which records SAN command failures and recovery */950950+ spin_lock_init(&adapter->san_dbf_lock);951951+ sprintf(dbf_name, "zfcp_%s_san", zfcp_get_busid_by_adapter(adapter));952952+ adapter->san_dbf = debug_register(dbf_name, dbfsize, 1,953953+ sizeof(struct zfcp_san_dbf_record));954954+ if (!adapter->san_dbf)955955+ goto failed;956956+ debug_register_view(adapter->san_dbf, &debug_hex_ascii_view);957957+ debug_register_view(adapter->san_dbf, &zfcp_san_dbf_view);958958+ debug_set_level(adapter->san_dbf, 6);959959+960960+ /* debug feature area which records SCSI command failures and recovery */961961+ spin_lock_init(&adapter->scsi_dbf_lock);962962+ sprintf(dbf_name, "zfcp_%s_scsi", zfcp_get_busid_by_adapter(adapter));963963+ adapter->scsi_dbf = debug_register(dbf_name, dbfsize, 1,964964+ sizeof(struct zfcp_scsi_dbf_record));965965+ if (!adapter->scsi_dbf)966966+ goto failed;967967+ debug_register_view(adapter->scsi_dbf, &debug_hex_ascii_view);968968+ debug_register_view(adapter->scsi_dbf, &zfcp_scsi_dbf_view);969969+ debug_set_level(adapter->scsi_dbf, 3);970970+971971+ return 0;972972+973973+ failed:974974+ zfcp_adapter_debug_unregister(adapter);975975+976976+ return -ENOMEM;977977+}978978+979979+/**980980+ * zfcp_adapter_debug_unregister - unregisters debug feature for an adapter981981+ * @adapter: pointer to adapter for which debug features should be unregistered982982+ */983983+void zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter)984984+{985985+ debug_unregister(adapter->scsi_dbf);986986+ debug_unregister(adapter->san_dbf);987987+ debug_unregister(adapter->hba_dbf);988988+ debug_unregister(adapter->erp_dbf);989989+ adapter->scsi_dbf = NULL;990990+ adapter->san_dbf = NULL;991991+ adapter->hba_dbf = NULL;992992+ adapter->erp_dbf = NULL;993993+}994994+995995+#undef ZFCP_LOG_AREA
+195-112
drivers/s390/scsi/zfcp_def.h
···6666/********************* GENERAL DEFINES *********************************/67676868/* zfcp version number, it consists of major, minor, and patch-level number */6969-#define ZFCP_VERSION "4.3.0"6969+#define ZFCP_VERSION "4.5.0"70707171/**7272 * zfcp_sg_to_address - determine kernel address from struct scatterlist···154154#define ZFCP_EXCHANGE_CONFIG_DATA_FIRST_SLEEP 100155155#define ZFCP_EXCHANGE_CONFIG_DATA_RETRIES 7156156157157+/* Retry 5 times every 2 second, then every minute */158158+#define ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES 5159159+#define ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP 200160160+#define ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP 6000161161+157162/* timeout value for "default timer" for fsf requests */158163#define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ);159164160165/*************** FIBRE CHANNEL PROTOCOL SPECIFIC DEFINES ********************/161166162167typedef unsigned long long wwn_t;163163-typedef unsigned int fc_id_t;164168typedef unsigned long long fcp_lun_t;165169/* data length field may be at variable position in FCP-2 FCP_CMND IU */166170typedef unsigned int fcp_dl_t;···285281} __attribute__((packed));286282287283/*284284+ * DBF stuff285285+ */286286+#define ZFCP_DBF_TAG_SIZE 4287287+288288+struct zfcp_dbf_dump {289289+ u8 tag[ZFCP_DBF_TAG_SIZE];290290+ u32 total_size; /* size of total dump data */291291+ u32 offset; /* how much data has being already dumped */292292+ u32 size; /* how much data comes with this record */293293+ u8 data[]; /* dump data */294294+} __attribute__ ((packed));295295+296296+/* FIXME: to be inflated when reworking the erp dbf */297297+struct zfcp_erp_dbf_record {298298+ u8 dummy[16];299299+} __attribute__ ((packed));300300+301301+struct zfcp_hba_dbf_record_response {302302+ u32 fsf_command;303303+ u64 fsf_reqid;304304+ u32 fsf_seqno;305305+ u64 fsf_issued;306306+ u32 fsf_prot_status;307307+ u32 fsf_status;308308+ u8 fsf_prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE];309309+ u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];310310+ u32 fsf_req_status;311311+ u8 sbal_first;312312+ u8 sbal_curr;313313+ u8 sbal_last;314314+ u8 pool;315315+ u64 erp_action;316316+ union {317317+ struct {318318+ u64 scsi_cmnd;319319+ u64 scsi_serial;320320+ } send_fcp;321321+ struct {322322+ u64 wwpn;323323+ u32 d_id;324324+ u32 port_handle;325325+ } port;326326+ struct {327327+ u64 wwpn;328328+ u64 fcp_lun;329329+ u32 port_handle;330330+ u32 lun_handle;331331+ } unit;332332+ struct {333333+ u32 d_id;334334+ u8 ls_code;335335+ } send_els;336336+ } data;337337+} __attribute__ ((packed));338338+339339+struct zfcp_hba_dbf_record_status {340340+ u8 failed;341341+ u32 status_type;342342+ u32 status_subtype;343343+ struct fsf_queue_designator344344+ queue_designator;345345+ u32 payload_size;346346+#define ZFCP_DBF_UNSOL_PAYLOAD 80347347+#define ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL 32348348+#define ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD 56349349+#define ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT 2 * sizeof(u32)350350+ u8 payload[ZFCP_DBF_UNSOL_PAYLOAD];351351+} __attribute__ ((packed));352352+353353+struct zfcp_hba_dbf_record_qdio {354354+ u32 status;355355+ u32 qdio_error;356356+ u32 siga_error;357357+ u8 sbal_index;358358+ u8 sbal_count;359359+} __attribute__ ((packed));360360+361361+struct zfcp_hba_dbf_record {362362+ u8 tag[ZFCP_DBF_TAG_SIZE];363363+ u8 tag2[ZFCP_DBF_TAG_SIZE];364364+ union {365365+ struct zfcp_hba_dbf_record_response response;366366+ struct zfcp_hba_dbf_record_status status;367367+ struct zfcp_hba_dbf_record_qdio qdio;368368+ } type;369369+} __attribute__ ((packed));370370+371371+struct zfcp_san_dbf_record_ct {372372+ union {373373+ struct {374374+ u16 cmd_req_code;375375+ u8 revision;376376+ u8 gs_type;377377+ u8 gs_subtype;378378+ u8 options;379379+ u16 max_res_size;380380+ } request;381381+ struct {382382+ u16 cmd_rsp_code;383383+ u8 revision;384384+ u8 reason_code;385385+ u8 reason_code_expl;386386+ u8 vendor_unique;387387+ } response;388388+ } type;389389+ u32 payload_size;390390+#define ZFCP_DBF_CT_PAYLOAD 24391391+ u8 payload[ZFCP_DBF_CT_PAYLOAD];392392+} __attribute__ ((packed));393393+394394+struct zfcp_san_dbf_record_els {395395+ u8 ls_code;396396+ u32 payload_size;397397+#define ZFCP_DBF_ELS_PAYLOAD 32398398+#define ZFCP_DBF_ELS_MAX_PAYLOAD 1024399399+ u8 payload[ZFCP_DBF_ELS_PAYLOAD];400400+} __attribute__ ((packed));401401+402402+struct zfcp_san_dbf_record {403403+ u8 tag[ZFCP_DBF_TAG_SIZE];404404+ u64 fsf_reqid;405405+ u32 fsf_seqno;406406+ u32 s_id;407407+ u32 d_id;408408+ union {409409+ struct zfcp_san_dbf_record_ct ct;410410+ struct zfcp_san_dbf_record_els els;411411+ } type;412412+} __attribute__ ((packed));413413+414414+struct zfcp_scsi_dbf_record {415415+ u8 tag[ZFCP_DBF_TAG_SIZE];416416+ u8 tag2[ZFCP_DBF_TAG_SIZE];417417+ u32 scsi_id;418418+ u32 scsi_lun;419419+ u32 scsi_result;420420+ u64 scsi_cmnd;421421+ u64 scsi_serial;422422+#define ZFCP_DBF_SCSI_OPCODE 16423423+ u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE];424424+ u8 scsi_retries;425425+ u8 scsi_allowed;426426+ u64 fsf_reqid;427427+ u32 fsf_seqno;428428+ u64 fsf_issued;429429+ union {430430+ struct {431431+ u64 fsf_reqid;432432+ u32 fsf_seqno;433433+ u64 fsf_issued;434434+ } new_fsf_req;435435+ struct {436436+ u8 rsp_validity;437437+ u8 rsp_scsi_status;438438+ u32 rsp_resid;439439+ u8 rsp_code;440440+#define ZFCP_DBF_SCSI_FCP_SNS_INFO 16441441+#define ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO 256442442+ u32 sns_info_len;443443+ u8 sns_info[ZFCP_DBF_SCSI_FCP_SNS_INFO];444444+ } fcp;445445+ } type;446446+} __attribute__ ((packed));447447+448448+/*288449 * FC-FS stuff289450 */290451#define R_A_TOV 10 /* seconds */···507338 * FC-GS-4 stuff508339 */509340#define ZFCP_CT_TIMEOUT (3 * R_A_TOV)510510-511511-512512-/***************** S390 DEBUG FEATURE SPECIFIC DEFINES ***********************/513513-514514-/* debug feature entries per adapter */515515-#define ZFCP_ERP_DBF_INDEX 1 516516-#define ZFCP_ERP_DBF_AREAS 2517517-#define ZFCP_ERP_DBF_LENGTH 16518518-#define ZFCP_ERP_DBF_LEVEL 3519519-#define ZFCP_ERP_DBF_NAME "zfcperp"520520-521521-#define ZFCP_CMD_DBF_INDEX 2522522-#define ZFCP_CMD_DBF_AREAS 1523523-#define ZFCP_CMD_DBF_LENGTH 8524524-#define ZFCP_CMD_DBF_LEVEL 3525525-#define ZFCP_CMD_DBF_NAME "zfcpcmd"526526-527527-#define ZFCP_ABORT_DBF_INDEX 2528528-#define ZFCP_ABORT_DBF_AREAS 1529529-#define ZFCP_ABORT_DBF_LENGTH 8530530-#define ZFCP_ABORT_DBF_LEVEL 6531531-#define ZFCP_ABORT_DBF_NAME "zfcpabt"532532-533533-#define ZFCP_IN_ELS_DBF_INDEX 2534534-#define ZFCP_IN_ELS_DBF_AREAS 1535535-#define ZFCP_IN_ELS_DBF_LENGTH 8536536-#define ZFCP_IN_ELS_DBF_LEVEL 6537537-#define ZFCP_IN_ELS_DBF_NAME "zfcpels"538341539342/******************** LOGGING MACROS AND DEFINES *****************************/540343···642501#define ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL 0x00000080643502#define ZFCP_STATUS_ADAPTER_ERP_PENDING 0x00000100644503#define ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED 0x00000200504504+#define ZFCP_STATUS_ADAPTER_XPORT_OK 0x00000800645505646506#define ZFCP_STATUS_ADAPTER_SCSI_UP \647507 (ZFCP_STATUS_COMMON_UNBLOCKED | \···777635 mempool_t *data_gid_pn;778636};779637780780-struct zfcp_exchange_config_data{781781-};782782-783783-struct zfcp_open_port {784784- struct zfcp_port *port;785785-};786786-787787-struct zfcp_close_port {788788- struct zfcp_port *port;789789-};790790-791791-struct zfcp_open_unit {792792- struct zfcp_unit *unit;793793-};794794-795795-struct zfcp_close_unit {796796- struct zfcp_unit *unit;797797-};798798-799799-struct zfcp_close_physical_port {800800- struct zfcp_port *port;801801-};802802-803803-struct zfcp_send_fcp_command_task {804804- struct zfcp_fsf_req *fsf_req;805805- struct zfcp_unit *unit;806806- struct scsi_cmnd *scsi_cmnd;807807- unsigned long start_jiffies;808808-};809809-810810-struct zfcp_send_fcp_command_task_management {811811- struct zfcp_unit *unit;812812-};813813-814814-struct zfcp_abort_fcp_command {815815- struct zfcp_fsf_req *fsf_req;816816- struct zfcp_unit *unit;817817-};818818-819638/*820639 * header for CT_IU821640 */···805702/* FS_ACC IU and data unit for GID_PN nameserver request */806703struct ct_iu_gid_pn_resp {807704 struct ct_hdr header;808808- fc_id_t d_id;705705+ u32 d_id;809706} __attribute__ ((packed));810707811708typedef void (*zfcp_send_ct_handler_t)(unsigned long);···871768struct zfcp_send_els {872769 struct zfcp_adapter *adapter;873770 struct zfcp_port *port;874874- fc_id_t d_id;771771+ u32 d_id;875772 struct scatterlist *req;876773 struct scatterlist *resp;877774 unsigned int req_count;···882779 struct completion *completion;883780 int ls_code;884781 int status;885885-};886886-887887-struct zfcp_status_read {888888- struct fsf_status_read_buffer *buffer;889889-};890890-891891-struct zfcp_fsf_done {892892- struct completion *complete;893893- int status;894894-};895895-896896-/* request specific data */897897-union zfcp_req_data {898898- struct zfcp_exchange_config_data exchange_config_data;899899- struct zfcp_open_port open_port;900900- struct zfcp_close_port close_port;901901- struct zfcp_open_unit open_unit;902902- struct zfcp_close_unit close_unit;903903- struct zfcp_close_physical_port close_physical_port;904904- struct zfcp_send_fcp_command_task send_fcp_command_task;905905- struct zfcp_send_fcp_command_task_management906906- send_fcp_command_task_management;907907- struct zfcp_abort_fcp_command abort_fcp_command;908908- struct zfcp_send_ct *send_ct;909909- struct zfcp_send_els *send_els;910910- struct zfcp_status_read status_read;911911- struct fsf_qtcb_bottom_port *port_data;912782};913783914784struct zfcp_qdio_queue {···914838 atomic_t refcount; /* reference count */915839 wait_queue_head_t remove_wq; /* can be used to wait for916840 refcount drop to zero */917917- wwn_t wwnn; /* WWNN */918918- wwn_t wwpn; /* WWPN */919919- fc_id_t s_id; /* N_Port ID */920841 wwn_t peer_wwnn; /* P2P peer WWNN */921842 wwn_t peer_wwpn; /* P2P peer WWPN */922922- fc_id_t peer_d_id; /* P2P peer D_ID */843843+ u32 peer_d_id; /* P2P peer D_ID */844844+ wwn_t physical_wwpn; /* WWPN of physical port */845845+ u32 physical_s_id; /* local FC port ID */923846 struct ccw_device *ccw_device; /* S/390 ccw device */924847 u8 fc_service_class;925848 u32 fc_topology; /* FC topology */926926- u32 fc_link_speed; /* FC interface speed */927849 u32 hydra_version; /* Hydra version */928850 u32 fsf_lic_version;929929- u32 supported_features;/* of FCP channel */851851+ u32 adapter_features; /* FCP channel features */852852+ u32 connection_features; /* host connection features */930853 u32 hardware_version; /* of FCP channel */931931- u8 serial_number[32]; /* of hardware */932854 struct Scsi_Host *scsi_host; /* Pointer to mid-layer */933855 unsigned short scsi_host_no; /* Assigned host number */934856 unsigned char name[9];···963889 u32 erp_low_mem_count; /* nr of erp actions waiting964890 for memory */965891 struct zfcp_port *nameserver_port; /* adapter's nameserver */966966- debug_info_t *erp_dbf; /* S/390 debug features */967967- debug_info_t *abort_dbf;968968- debug_info_t *in_els_dbf;969969- debug_info_t *cmd_dbf;970970- spinlock_t dbf_lock;892892+ debug_info_t *erp_dbf;893893+ debug_info_t *hba_dbf;894894+ debug_info_t *san_dbf; /* debug feature areas */895895+ debug_info_t *scsi_dbf;896896+ spinlock_t erp_dbf_lock;897897+ spinlock_t hba_dbf_lock;898898+ spinlock_t san_dbf_lock;899899+ spinlock_t scsi_dbf_lock;900900+ struct zfcp_erp_dbf_record erp_dbf_buf;901901+ struct zfcp_hba_dbf_record hba_dbf_buf;902902+ struct zfcp_san_dbf_record san_dbf_buf;903903+ struct zfcp_scsi_dbf_record scsi_dbf_buf;971904 struct zfcp_adapter_mempool pool; /* Adapter memory pools */972905 struct qdio_initialize qdio_init_data; /* for qdio_establish */973906 struct device generic_services; /* directory for WKA ports */···1000919 atomic_t status; /* status of this remote port */1001920 wwn_t wwnn; /* WWNN if known */1002921 wwn_t wwpn; /* WWPN */10031003- fc_id_t d_id; /* D_ID */922922+ u32 d_id; /* D_ID */1004923 u32 handle; /* handle assigned by FSF */1005924 struct zfcp_erp_action erp_action; /* pending error recovery */1006925 atomic_t erp_counter;···1044963 u32 fsf_command; /* FSF Command copy */1045964 struct fsf_qtcb *qtcb; /* address of associated QTCB */1046965 u32 seq_no; /* Sequence number of request */10471047- union zfcp_req_data data; /* Info fields of request */ 966966+ unsigned long data; /* private data of request */ 1048967 struct zfcp_erp_action *erp_action; /* used if this request is1049968 issued on behalf of erp */1050969 mempool_t *pool; /* used if request was alloacted1051970 from emergency pool */971971+ unsigned long long issued; /* request sent time (STCK) */972972+ struct zfcp_unit *unit;1052973};10539741054975typedef void zfcp_fsf_req_handler_t(struct zfcp_fsf_req*);
+112-23
drivers/s390/scsi/zfcp_erp.c
···8282static int zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *);8383static int zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *);8484static int zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *);8585+static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *);8586static int zfcp_erp_adapter_strategy_open_fsf_statusread(8687 struct zfcp_erp_action *);8788···346345347346 /* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports348347 without FC-AL-2 capability, so we don't set it */349349- adisc->wwpn = adapter->wwpn;350350- adisc->wwnn = adapter->wwnn;351351- adisc->nport_id = adapter->s_id;348348+ adisc->wwpn = fc_host_port_name(adapter->scsi_host);349349+ adisc->wwnn = fc_host_node_name(adapter->scsi_host);350350+ adisc->nport_id = fc_host_port_id(adapter->scsi_host);352351 ZFCP_LOG_INFO("ADISC request from s_id 0x%08x to d_id 0x%08x "353352 "(wwpn=0x%016Lx, wwnn=0x%016Lx, "354353 "hard_nport_id=0x%08x, nport_id=0x%08x)\n",355355- adapter->s_id, send_els->d_id, (wwn_t) adisc->wwpn,354354+ adisc->nport_id, send_els->d_id, (wwn_t) adisc->wwpn,356355 (wwn_t) adisc->wwnn, adisc->hard_nport_id,357356 adisc->nport_id);358357···405404 struct zfcp_send_els *send_els;406405 struct zfcp_port *port;407406 struct zfcp_adapter *adapter;408408- fc_id_t d_id;407407+ u32 d_id;409408 struct zfcp_ls_adisc_acc *adisc;410409411410 send_els = (struct zfcp_send_els *) data;···436435 ZFCP_LOG_INFO("ADISC response from d_id 0x%08x to s_id "437436 "0x%08x (wwpn=0x%016Lx, wwnn=0x%016Lx, "438437 "hard_nport_id=0x%08x, nport_id=0x%08x)\n",439439- d_id, adapter->s_id, (wwn_t) adisc->wwpn,440440- (wwn_t) adisc->wwnn, adisc->hard_nport_id,441441- adisc->nport_id);438438+ d_id, fc_host_port_id(adapter->scsi_host),439439+ (wwn_t) adisc->wwpn, (wwn_t) adisc->wwnn,440440+ adisc->hard_nport_id, adisc->nport_id);442441443442 /* set wwnn for port */444443 if (port->wwnn == 0)···887886zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)888887{889888 int retval = 0;890890- struct zfcp_fsf_req *fsf_req;889889+ struct zfcp_fsf_req *fsf_req = NULL;891890 struct zfcp_adapter *adapter = erp_action->adapter;892891893892 if (erp_action->fsf_req) {···897896 list_for_each_entry(fsf_req, &adapter->fsf_req_list_head, list)898897 if (fsf_req == erp_action->fsf_req)899898 break;900900- if (fsf_req == erp_action->fsf_req) {899899+ if (fsf_req && (fsf_req->erp_action == erp_action)) {901900 /* fsf_req still exists */902901 debug_text_event(adapter->erp_dbf, 3, "a_ca_req");903902 debug_event(adapter->erp_dbf, 3, &fsf_req,···22592258static int22602259zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *erp_action)22612260{22622262- int retval;22612261+ int xconfig, xport;2263226222642264- /* do 'exchange configuration data' */22652265- retval = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action);22662266- if (retval == ZFCP_ERP_FAILED)22672267- return retval;22632263+ if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,22642264+ &erp_action->adapter->status)) {22652265+ zfcp_erp_adapter_strategy_open_fsf_xport(erp_action);22662266+ atomic_set(&erp_action->adapter->erp_counter, 0);22672267+ return ZFCP_ERP_FAILED;22682268+ }2268226922692269- /* start the desired number of Status Reads */22702270- retval = zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action);22712271- return retval;22702270+ xconfig = zfcp_erp_adapter_strategy_open_fsf_xconfig(erp_action);22712271+ xport = zfcp_erp_adapter_strategy_open_fsf_xport(erp_action);22722272+ if ((xconfig == ZFCP_ERP_FAILED) || (xport == ZFCP_ERP_FAILED))22732273+ return ZFCP_ERP_FAILED;22742274+22752275+ return zfcp_erp_adapter_strategy_open_fsf_statusread(erp_action);22722276}2273227722742278/*···22972291 atomic_clear_mask(ZFCP_STATUS_ADAPTER_HOST_CON_INIT,22982292 &adapter->status);22992293 ZFCP_LOG_DEBUG("Doing exchange config data\n");22942294+ write_lock(&adapter->erp_lock);23002295 zfcp_erp_action_to_running(erp_action);22962296+ write_unlock(&adapter->erp_lock);23012297 zfcp_erp_timeout_init(erp_action);23022298 if (zfcp_fsf_exchange_config_data(erp_action)) {23032299 retval = ZFCP_ERP_FAILED;···23482340 if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,23492341 &adapter->status)) {23502342 ZFCP_LOG_INFO("error: exchange of configuration data for "23432343+ "adapter %s failed\n",23442344+ zfcp_get_busid_by_adapter(adapter));23452345+ retval = ZFCP_ERP_FAILED;23462346+ }23472347+23482348+ return retval;23492349+}23502350+23512351+static int23522352+zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action)23532353+{23542354+ int retval = ZFCP_ERP_SUCCEEDED;23552355+ int retries;23562356+ int sleep;23572357+ struct zfcp_adapter *adapter = erp_action->adapter;23582358+23592359+ atomic_clear_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);23602360+23612361+ for (retries = 0; ; retries++) {23622362+ ZFCP_LOG_DEBUG("Doing exchange port data\n");23632363+ zfcp_erp_action_to_running(erp_action);23642364+ zfcp_erp_timeout_init(erp_action);23652365+ if (zfcp_fsf_exchange_port_data(erp_action, adapter, NULL)) {23662366+ retval = ZFCP_ERP_FAILED;23672367+ debug_text_event(adapter->erp_dbf, 5, "a_fstx_xf");23682368+ ZFCP_LOG_INFO("error: initiation of exchange of "23692369+ "port data failed for adapter %s\n",23702370+ zfcp_get_busid_by_adapter(adapter));23712371+ break;23722372+ }23732373+ debug_text_event(adapter->erp_dbf, 6, "a_fstx_xok");23742374+ ZFCP_LOG_DEBUG("Xchange underway\n");23752375+23762376+ /*23772377+ * Why this works:23782378+ * Both the normal completion handler as well as the timeout23792379+ * handler will do an 'up' when the 'exchange port data'23802380+ * request completes or times out. Thus, the signal to go on23812381+ * won't be lost utilizing this semaphore.23822382+ * Furthermore, this 'adapter_reopen' action is23832383+ * guaranteed to be the only action being there (highest action23842384+ * which prevents other actions from being created).23852385+ * Resulting from that, the wake signal recognized here23862386+ * _must_ be the one belonging to the 'exchange port23872387+ * data' request.23882388+ */23892389+ down(&adapter->erp_ready_sem);23902390+ if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {23912391+ ZFCP_LOG_INFO("error: exchange of port data "23922392+ "for adapter %s timed out\n",23932393+ zfcp_get_busid_by_adapter(adapter));23942394+ break;23952395+ }23962396+23972397+ if (!atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,23982398+ &adapter->status))23992399+ break;24002400+24012401+ ZFCP_LOG_DEBUG("host connection still initialising... "24022402+ "waiting and retrying...\n");24032403+ /* sleep a little bit before retry */24042404+ sleep = retries < ZFCP_EXCHANGE_PORT_DATA_SHORT_RETRIES ?24052405+ ZFCP_EXCHANGE_PORT_DATA_SHORT_SLEEP :24062406+ ZFCP_EXCHANGE_PORT_DATA_LONG_SLEEP;24072407+ msleep(jiffies_to_msecs(sleep));24082408+ }24092409+24102410+ if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,24112411+ &adapter->status)) {24122412+ ZFCP_LOG_INFO("error: exchange of port data for "23512413 "adapter %s failed\n",23522414 zfcp_get_busid_by_adapter(adapter));23532415 retval = ZFCP_ERP_FAILED;···32723194 /* fall through !!! */3273319532743196 case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:32753275- if (atomic_test_mask32763276- (ZFCP_STATUS_COMMON_ERP_INUSE, &port->status)32773277- && port->erp_action.action ==32783278- ZFCP_ERP_ACTION_REOPEN_PORT_FORCED) {32793279- debug_text_event(adapter->erp_dbf, 4, "pf_actenq_drp");31973197+ if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE,31983198+ &port->status)) {31993199+ if (port->erp_action.action !=32003200+ ZFCP_ERP_ACTION_REOPEN_PORT_FORCED) {32013201+ ZFCP_LOG_INFO("dropped erp action %i (port "32023202+ "0x%016Lx, action in use: %i)\n",32033203+ action, port->wwpn,32043204+ port->erp_action.action);32053205+ debug_text_event(adapter->erp_dbf, 4,32063206+ "pf_actenq_drp");32073207+ } else 32083208+ debug_text_event(adapter->erp_dbf, 4,32093209+ "pf_actenq_drpcp");32803210 debug_event(adapter->erp_dbf, 4, &port->wwpn,32813211 sizeof (wwn_t));32823212 goto out;···36743588{36753589 struct zfcp_port *port;36763590 unsigned long flags;35913591+35923592+ if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)35933593+ return;3677359436783595 debug_text_event(adapter->erp_dbf, 3, "a_access_recover");36793596 debug_event(adapter->erp_dbf, 3, &adapter->name, 8);
···5454static qdio_handler_t zfcp_qdio_request_handler;5555static qdio_handler_t zfcp_qdio_response_handler;5656static int zfcp_qdio_handler_error_check(struct zfcp_adapter *,5757- unsigned int,5858- unsigned int, unsigned int);5757+ unsigned int, unsigned int, unsigned int, int, int);59586059#define ZFCP_LOG_AREA ZFCP_LOG_AREA_QDIO6160···213214 *214215 */215216static inline int216216-zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter,217217- unsigned int status,218218- unsigned int qdio_error, unsigned int siga_error)217217+zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, unsigned int status,218218+ unsigned int qdio_error, unsigned int siga_error,219219+ int first_element, int elements_processed)219220{220221 int retval = 0;221222222222- if (ZFCP_LOG_CHECK(ZFCP_LOG_LEVEL_TRACE)) {223223- if (status & QDIO_STATUS_INBOUND_INT) {224224- ZFCP_LOG_TRACE("status is"225225- " QDIO_STATUS_INBOUND_INT \n");226226- }227227- if (status & QDIO_STATUS_OUTBOUND_INT) {228228- ZFCP_LOG_TRACE("status is"229229- " QDIO_STATUS_OUTBOUND_INT \n");230230- }231231- }232223 if (unlikely(status & QDIO_STATUS_LOOK_FOR_ERROR)) {233224 retval = -EIO;234225···226237 "qdio_error=0x%x, siga_error=0x%x)\n",227238 status, qdio_error, siga_error);228239229229- /* Restarting IO on the failed adapter from scratch */230230- debug_text_event(adapter->erp_dbf, 1, "qdio_err");240240+ zfcp_hba_dbf_event_qdio(adapter, status, qdio_error, siga_error,241241+ first_element, elements_processed);231242 /*243243+ * Restarting IO on the failed adapter from scratch.232244 * Since we have been using this adapter, it is save to assume233245 * that it is not failed but recoverable. The card seems to234246 * report link-up events by self-initiated queue shutdown.···272282 first_element, elements_processed);273283274284 if (unlikely(zfcp_qdio_handler_error_check(adapter, status, qdio_error,275275- siga_error)))285285+ siga_error, first_element,286286+ elements_processed)))276287 goto out;277288 /*278289 * we stored address of struct zfcp_adapter data structure···325334 queue = &adapter->response_queue;326335327336 if (unlikely(zfcp_qdio_handler_error_check(adapter, status, qdio_error,328328- siga_error)))337337+ siga_error, first_element,338338+ elements_processed)))329339 goto out;330340331341 /*
+82-213
drivers/s390/scsi/zfcp_scsi.c
···4444static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *);4545static int zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *);4646static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *);4747-static int zfcp_task_management_function(struct zfcp_unit *, u8);4747+static int zfcp_task_management_function(struct zfcp_unit *, u8,4848+ struct scsi_cmnd *);48494950static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int, scsi_id_t,5051 scsi_lun_t);···243242zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result)244243{245244 set_host_byte(&scpnt->result, result);246246- zfcp_cmd_dbf_event_scsi("failing", scpnt);245245+ if ((scpnt->device != NULL) && (scpnt->device->host != NULL))246246+ zfcp_scsi_dbf_event_result("fail", 4,247247+ (struct zfcp_adapter*) scpnt->device->host->hostdata[0],248248+ scpnt);247249 /* return directly */248250 scpnt->scsi_done(scpnt);249251}···418414 return (struct zfcp_port *) NULL;419415}420416421421-/*422422- * function: zfcp_scsi_eh_abort_handler417417+/**418418+ * zfcp_scsi_eh_abort_handler - abort the specified SCSI command419419+ * @scpnt: pointer to scsi_cmnd to be aborted 420420+ * Return: SUCCESS - command has been aborted and cleaned up in internal421421+ * bookkeeping, SCSI stack won't be called for aborted command422422+ * FAILED - otherwise423423 *424424- * purpose: tries to abort the specified (timed out) SCSI command425425- *426426- * note: We do not need to care for a SCSI command which completes427427- * normally but late during this abort routine runs.428428- * We are allowed to return late commands to the SCSI stack.429429- * It tracks the state of commands and will handle late commands.430430- * (Usually, the normal completion of late commands is ignored with431431- * respect to the running abort operation. Grep for 'done_late'432432- * in the SCSI stacks sources.)433433- *434434- * returns: SUCCESS - command has been aborted and cleaned up in internal435435- * bookkeeping,436436- * SCSI stack won't be called for aborted command437437- * FAILED - otherwise424424+ * We do not need to care for a SCSI command which completes normally425425+ * but late during this abort routine runs. We are allowed to return426426+ * late commands to the SCSI stack. It tracks the state of commands and427427+ * will handle late commands. (Usually, the normal completion of late428428+ * commands is ignored with respect to the running abort operation.)438429 */439430int440440-__zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)431431+zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)441432{433433+ struct Scsi_Host *scsi_host;434434+ struct zfcp_adapter *adapter;435435+ struct zfcp_unit *unit;442436 int retval = SUCCESS;443443- struct zfcp_fsf_req *new_fsf_req, *old_fsf_req;444444- struct zfcp_adapter *adapter = (struct zfcp_adapter *) scpnt->device->host->hostdata[0];445445- struct zfcp_unit *unit = (struct zfcp_unit *) scpnt->device->hostdata;446446- struct zfcp_port *port = unit->port;447447- struct Scsi_Host *scsi_host = scpnt->device->host;448448- union zfcp_req_data *req_data = NULL;437437+ struct zfcp_fsf_req *new_fsf_req = NULL;438438+ struct zfcp_fsf_req *old_fsf_req;449439 unsigned long flags;450450- u32 status = 0;451440452452- /* the components of a abort_dbf record (fixed size record) */453453- u64 dbf_scsi_cmnd = (unsigned long) scpnt;454454- char dbf_opcode[ZFCP_ABORT_DBF_LENGTH];455455- wwn_t dbf_wwn = port->wwpn;456456- fcp_lun_t dbf_fcp_lun = unit->fcp_lun;457457- u64 dbf_retries = scpnt->retries;458458- u64 dbf_allowed = scpnt->allowed;459459- u64 dbf_timeout = 0;460460- u64 dbf_fsf_req = 0;461461- u64 dbf_fsf_status = 0;462462- u64 dbf_fsf_qual[2] = { 0, 0 };463463- char dbf_result[ZFCP_ABORT_DBF_LENGTH] = "##undef";464464-465465- memset(dbf_opcode, 0, ZFCP_ABORT_DBF_LENGTH);466466- memcpy(dbf_opcode,467467- scpnt->cmnd,468468- min(scpnt->cmd_len, (unsigned char) ZFCP_ABORT_DBF_LENGTH));441441+ scsi_host = scpnt->device->host;442442+ adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];443443+ unit = (struct zfcp_unit *) scpnt->device->hostdata;469444470445 ZFCP_LOG_INFO("aborting scsi_cmnd=%p on adapter %s\n",471446 scpnt, zfcp_get_busid_by_adapter(adapter));472447473473- spin_unlock_irq(scsi_host->host_lock);474474-475475- /*476476- * Race condition between normal (late) completion and abort has477477- * to be avoided.478478- * The entirity of all accesses to scsi_req have to be atomic.479479- * scsi_req is usually part of the fsf_req and thus we block the480480- * release of fsf_req as long as we need to access scsi_req.481481- */448448+ /* avoid race condition between late normal completion and abort */482449 write_lock_irqsave(&adapter->abort_lock, flags);483450484451 /*···459484 * this routine returns. (scpnt is parameter passed to this routine460485 * and must not disappear during abort even on late completion.)461486 */462462- req_data = (union zfcp_req_data *) scpnt->host_scribble;463463- /* DEBUG */464464- ZFCP_LOG_DEBUG("req_data=%p\n", req_data);465465- if (!req_data) {466466- ZFCP_LOG_DEBUG("late command completion overtook abort\n");467467- /*468468- * That's it.469469- * Do not initiate abort but return SUCCESS.470470- */471471- write_unlock_irqrestore(&adapter->abort_lock, flags);472472- retval = SUCCESS;473473- strncpy(dbf_result, "##late1", ZFCP_ABORT_DBF_LENGTH);474474- goto out;475475- }476476-477477- /* Figure out which fsf_req needs to be aborted. */478478- old_fsf_req = req_data->send_fcp_command_task.fsf_req;479479-480480- dbf_fsf_req = (unsigned long) old_fsf_req;481481- dbf_timeout =482482- (jiffies - req_data->send_fcp_command_task.start_jiffies) / HZ;483483-484484- ZFCP_LOG_DEBUG("old_fsf_req=%p\n", old_fsf_req);487487+ old_fsf_req = (struct zfcp_fsf_req *) scpnt->host_scribble;485488 if (!old_fsf_req) {486489 write_unlock_irqrestore(&adapter->abort_lock, flags);487487- ZFCP_LOG_NORMAL("bug: no old fsf request found\n");488488- ZFCP_LOG_NORMAL("req_data:\n");489489- ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,490490- (char *) req_data, sizeof (union zfcp_req_data));491491- ZFCP_LOG_NORMAL("scsi_cmnd:\n");492492- ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,493493- (char *) scpnt, sizeof (struct scsi_cmnd));494494- retval = FAILED;495495- strncpy(dbf_result, "##bug:r", ZFCP_ABORT_DBF_LENGTH);490490+ zfcp_scsi_dbf_event_abort("lte1", adapter, scpnt, new_fsf_req);491491+ retval = SUCCESS;496492 goto out;497493 }498498- old_fsf_req->data.send_fcp_command_task.scsi_cmnd = NULL;499499- /* mark old request as being aborted */494494+ old_fsf_req->data = 0;500495 old_fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTING;501501- /*502502- * We have to collect all information (e.g. unit) needed by 503503- * zfcp_fsf_abort_fcp_command before calling that routine504504- * since that routine is not allowed to access505505- * fsf_req which it is going to abort.506506- * This is because of we need to release fsf_req_list_lock507507- * before calling zfcp_fsf_abort_fcp_command.508508- * Since this lock will not be held, fsf_req may complete509509- * late and may be released meanwhile.510510- */511511- ZFCP_LOG_DEBUG("unit 0x%016Lx (%p)\n", unit->fcp_lun, unit);512496513513- /*514514- * We block (call schedule)515515- * That's why we must release the lock and enable the516516- * interrupts before.517517- * On the other hand we do not need the lock anymore since518518- * all critical accesses to scsi_req are done.519519- */497497+ /* don't access old_fsf_req after releasing the abort_lock */520498 write_unlock_irqrestore(&adapter->abort_lock, flags);521499 /* call FSF routine which does the abort */522500 new_fsf_req = zfcp_fsf_abort_fcp_command((unsigned long) old_fsf_req,523501 adapter, unit, 0);524524- ZFCP_LOG_DEBUG("new_fsf_req=%p\n", new_fsf_req);525502 if (!new_fsf_req) {503503+ ZFCP_LOG_INFO("error: initiation of Abort FCP Cmnd failed\n");526504 retval = FAILED;527527- ZFCP_LOG_NORMAL("error: initiation of Abort FCP Cmnd "528528- "failed\n");529529- strncpy(dbf_result, "##nores", ZFCP_ABORT_DBF_LENGTH);530505 goto out;531506 }532507533508 /* wait for completion of abort */534534- ZFCP_LOG_DEBUG("waiting for cleanup...\n");535535-#if 1536536- /*537537- * FIXME:538538- * copying zfcp_fsf_req_wait_and_cleanup code is not really nice539539- */540509 __wait_event(new_fsf_req->completion_wq,541510 new_fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);542542- status = new_fsf_req->status;543543- dbf_fsf_status = new_fsf_req->qtcb->header.fsf_status;544544- /*545545- * Ralphs special debug load provides timestamps in the FSF546546- * status qualifier. This might be specified later if being547547- * useful for debugging aborts.548548- */549549- dbf_fsf_qual[0] =550550- *(u64 *) & new_fsf_req->qtcb->header.fsf_status_qual.word[0];551551- dbf_fsf_qual[1] =552552- *(u64 *) & new_fsf_req->qtcb->header.fsf_status_qual.word[2];553553- zfcp_fsf_req_free(new_fsf_req);554554-#else555555- retval = zfcp_fsf_req_wait_and_cleanup(new_fsf_req,556556- ZFCP_UNINTERRUPTIBLE, &status);557557-#endif558558- ZFCP_LOG_DEBUG("Waiting for cleanup complete, status=0x%x\n", status);511511+559512 /* status should be valid since signals were not permitted */560560- if (status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) {513513+ if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTSUCCEEDED) {514514+ zfcp_scsi_dbf_event_abort("okay", adapter, scpnt, new_fsf_req);561515 retval = SUCCESS;562562- strncpy(dbf_result, "##succ", ZFCP_ABORT_DBF_LENGTH);563563- } else if (status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) {516516+ } else if (new_fsf_req->status & ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED) {517517+ zfcp_scsi_dbf_event_abort("lte2", adapter, scpnt, new_fsf_req);564518 retval = SUCCESS;565565- strncpy(dbf_result, "##late2", ZFCP_ABORT_DBF_LENGTH);566519 } else {520520+ zfcp_scsi_dbf_event_abort("fail", adapter, scpnt, new_fsf_req);567521 retval = FAILED;568568- strncpy(dbf_result, "##fail", ZFCP_ABORT_DBF_LENGTH);569522 }570570-523523+ zfcp_fsf_req_free(new_fsf_req);571524 out:572572- debug_event(adapter->abort_dbf, 1, &dbf_scsi_cmnd, sizeof (u64));573573- debug_event(adapter->abort_dbf, 1, &dbf_opcode, ZFCP_ABORT_DBF_LENGTH);574574- debug_event(adapter->abort_dbf, 1, &dbf_wwn, sizeof (wwn_t));575575- debug_event(adapter->abort_dbf, 1, &dbf_fcp_lun, sizeof (fcp_lun_t));576576- debug_event(adapter->abort_dbf, 1, &dbf_retries, sizeof (u64));577577- debug_event(adapter->abort_dbf, 1, &dbf_allowed, sizeof (u64));578578- debug_event(adapter->abort_dbf, 1, &dbf_timeout, sizeof (u64));579579- debug_event(adapter->abort_dbf, 1, &dbf_fsf_req, sizeof (u64));580580- debug_event(adapter->abort_dbf, 1, &dbf_fsf_status, sizeof (u64));581581- debug_event(adapter->abort_dbf, 1, &dbf_fsf_qual[0], sizeof (u64));582582- debug_event(adapter->abort_dbf, 1, &dbf_fsf_qual[1], sizeof (u64));583583- debug_text_event(adapter->abort_dbf, 1, dbf_result);584584-585585- spin_lock_irq(scsi_host->host_lock);586525 return retval;587587-}588588-589589-int590590-zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)591591-{592592- int rc;593593- struct Scsi_Host *scsi_host = scpnt->device->host;594594- spin_lock_irq(scsi_host->host_lock);595595- rc = __zfcp_scsi_eh_abort_handler(scpnt);596596- spin_unlock_irq(scsi_host->host_lock);597597- return rc;598526}599527600528/*···529651 */530652 if (!atomic_test_mask(ZFCP_STATUS_UNIT_NOTSUPPUNITRESET,531653 &unit->status)) {532532- retval =533533- zfcp_task_management_function(unit, FCP_LOGICAL_UNIT_RESET);654654+ retval = zfcp_task_management_function(unit,655655+ FCP_LOGICAL_UNIT_RESET,656656+ scpnt);534657 if (retval) {535658 ZFCP_LOG_DEBUG("unit reset failed (unit=%p)\n", unit);536659 if (retval == -ENOTSUPP)···547668 goto out;548669 }549670 }550550- retval = zfcp_task_management_function(unit, FCP_TARGET_RESET);671671+ retval = zfcp_task_management_function(unit, FCP_TARGET_RESET, scpnt);551672 if (retval) {552673 ZFCP_LOG_DEBUG("target reset failed (unit=%p)\n", unit);553674 retval = FAILED;···560681}561682562683static int563563-zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags)684684+zfcp_task_management_function(struct zfcp_unit *unit, u8 tm_flags,685685+ struct scsi_cmnd *scpnt)564686{565687 struct zfcp_adapter *adapter = unit->port->adapter;566566- int retval;567567- int status;568688 struct zfcp_fsf_req *fsf_req;689689+ int retval = 0;569690570691 /* issue task management function */571692 fsf_req = zfcp_fsf_send_fcp_command_task_management···575696 "failed for unit 0x%016Lx on port 0x%016Lx on "576697 "adapter %s\n", unit->fcp_lun, unit->port->wwpn,577698 zfcp_get_busid_by_adapter(adapter));699699+ zfcp_scsi_dbf_event_devreset("nres", tm_flags, unit, scpnt);578700 retval = -ENOMEM;579701 goto out;580702 }581703582582- retval = zfcp_fsf_req_wait_and_cleanup(fsf_req,583583- ZFCP_UNINTERRUPTIBLE, &status);704704+ __wait_event(fsf_req->completion_wq,705705+ fsf_req->status & ZFCP_STATUS_FSFREQ_COMPLETED);706706+584707 /*585708 * check completion status of task management function586586- * (status should always be valid since no signals permitted)587709 */588588- if (status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED)710710+ if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) {711711+ zfcp_scsi_dbf_event_devreset("fail", tm_flags, unit, scpnt);589712 retval = -EIO;590590- else if (status & ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP)713713+ } else if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCNOTSUPP) {714714+ zfcp_scsi_dbf_event_devreset("nsup", tm_flags, unit, scpnt);591715 retval = -ENOTSUPP;592592- else593593- retval = 0;716716+ } else717717+ zfcp_scsi_dbf_event_devreset("okay", tm_flags, unit, scpnt);718718+719719+ zfcp_fsf_req_free(fsf_req);594720 out:595721 return retval;596722}597723598598-/*599599- * function: zfcp_scsi_eh_bus_reset_handler600600- *601601- * purpose:602602- *603603- * returns:724724+/**725725+ * zfcp_scsi_eh_bus_reset_handler - reset bus (reopen adapter)604726 */605727int606728zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *scpnt)607729{608608- int retval = 0;609609- struct zfcp_unit *unit;730730+ struct zfcp_unit *unit = (struct zfcp_unit*) scpnt->device->hostdata;731731+ struct zfcp_adapter *adapter = unit->port->adapter;610732611611- unit = (struct zfcp_unit *) scpnt->device->hostdata;612733 ZFCP_LOG_NORMAL("bus reset because of problems with "613734 "unit 0x%016Lx\n", unit->fcp_lun);614614- zfcp_erp_adapter_reopen(unit->port->adapter, 0);615615- zfcp_erp_wait(unit->port->adapter);616616- retval = SUCCESS;735735+ zfcp_erp_adapter_reopen(adapter, 0);736736+ zfcp_erp_wait(adapter);617737618618- return retval;738738+ return SUCCESS;619739}620740621621-/*622622- * function: zfcp_scsi_eh_host_reset_handler623623- *624624- * purpose:625625- *626626- * returns:741741+/**742742+ * zfcp_scsi_eh_host_reset_handler - reset host (reopen adapter)627743 */628744int629745zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)630746{631631- int retval = 0;632632- struct zfcp_unit *unit;747747+ struct zfcp_unit *unit = (struct zfcp_unit*) scpnt->device->hostdata;748748+ struct zfcp_adapter *adapter = unit->port->adapter;633749634634- unit = (struct zfcp_unit *) scpnt->device->hostdata;635750 ZFCP_LOG_NORMAL("host reset because of problems with "636751 "unit 0x%016Lx\n", unit->fcp_lun);637637- zfcp_erp_adapter_reopen(unit->port->adapter, 0);638638- zfcp_erp_wait(unit->port->adapter);639639- retval = SUCCESS;752752+ zfcp_erp_adapter_reopen(adapter, 0);753753+ zfcp_erp_wait(adapter);640754641641- return retval;755755+ return SUCCESS;642756}643757644758/*···698826zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter)699827{700828 struct Scsi_Host *shost;829829+ struct zfcp_port *port;701830702831 shost = adapter->scsi_host;703832 if (!shost)704833 return;834834+ read_lock_irq(&zfcp_data.config_lock);835835+ list_for_each_entry(port, &adapter->port_list_head, list)836836+ if (port->rport)837837+ port->rport = NULL;838838+ read_unlock_irq(&zfcp_data.config_lock);705839 fc_remove_host(shost);706840 scsi_remove_host(shost);707841 scsi_host_put(shost);···782904 read_unlock_irqrestore(&zfcp_data.config_lock, flags);783905}784906785785-void786786-zfcp_set_fc_host_attrs(struct zfcp_adapter *adapter)787787-{788788- struct Scsi_Host *shost = adapter->scsi_host;789789-790790- fc_host_node_name(shost) = adapter->wwnn;791791- fc_host_port_name(shost) = adapter->wwpn;792792- strncpy(fc_host_serial_number(shost), adapter->serial_number,793793- min(FC_SERIAL_NUMBER_SIZE, 32));794794- fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3;795795-}796796-797907struct fc_function_template zfcp_transport_functions = {798908 .get_starget_port_id = zfcp_get_port_id,799909 .get_starget_port_name = zfcp_get_port_name,···793927 .show_host_node_name = 1,794928 .show_host_port_name = 1,795929 .show_host_supported_classes = 1,930930+ .show_host_maxframe_size = 1,796931 .show_host_serial_number = 1,932932+ .show_host_speed = 1,933933+ .show_host_port_id = 1,797934};798935799936/**
···11091109 return (0);11101110}1111111111121112-uint64_t11131113-ahc_linux_get_memsize(void)11141114-{11151115- struct sysinfo si;11161116-11171117- si_meminfo(&si);11181118- return ((uint64_t)si.totalram << PAGE_SHIFT);11191119-}11201120-11211112/*11221113 * Place the SCSI bus into a known state by either resetting it,11231114 * or forcing transfer negotiations on the next command to any
···442442 * piix_set_piomode - Initialize host controller PATA PIO timings443443 * @ap: Port whose timings we are configuring444444 * @adev: um445445- * @pio: PIO mode, 0 - 4446445 *447446 * Set PIO mode for device, in host controller PCI config space.448447 *
···9898 switch (oldstate) {9999 case SHOST_CREATED:100100 case SHOST_RUNNING:101101+ case SHOST_CANCEL_RECOVERY:101102 break;102103 default:103104 goto illegal;···108107 case SHOST_DEL:109108 switch (oldstate) {110109 case SHOST_CANCEL:110110+ case SHOST_DEL_RECOVERY:111111 break;112112 default:113113 goto illegal;114114 }115115 break;116116117117+ case SHOST_CANCEL_RECOVERY:118118+ switch (oldstate) {119119+ case SHOST_CANCEL:120120+ case SHOST_RECOVERY:121121+ break;122122+ default:123123+ goto illegal;124124+ }125125+ break;126126+127127+ case SHOST_DEL_RECOVERY:128128+ switch (oldstate) {129129+ case SHOST_CANCEL_RECOVERY:130130+ break;131131+ default:132132+ goto illegal;133133+ }134134+ break;117135 }118136 shost->shost_state = state;119137 return 0;···154134 **/155135void scsi_remove_host(struct Scsi_Host *shost)156136{137137+ unsigned long flags;157138 down(&shost->scan_mutex);158158- scsi_host_set_state(shost, SHOST_CANCEL);139139+ spin_lock_irqsave(shost->host_lock, flags);140140+ if (scsi_host_set_state(shost, SHOST_CANCEL))141141+ if (scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY)) {142142+ spin_unlock_irqrestore(shost->host_lock, flags);143143+ up(&shost->scan_mutex);144144+ return;145145+ }146146+ spin_unlock_irqrestore(shost->host_lock, flags);159147 up(&shost->scan_mutex);160148 scsi_forget_host(shost);161149 scsi_proc_host_rm(shost);162150163163- scsi_host_set_state(shost, SHOST_DEL);151151+ spin_lock_irqsave(shost->host_lock, flags);152152+ if (scsi_host_set_state(shost, SHOST_DEL))153153+ BUG_ON(scsi_host_set_state(shost, SHOST_DEL_RECOVERY));154154+ spin_unlock_irqrestore(shost->host_lock, flags);164155165156 transport_unregister_device(&shost->shost_gendev);166157 class_device_unregister(&shost->shost_classdev);
+2
drivers/scsi/ibmmca.c
···460460MODULE_PARM(normal, "1i");461461MODULE_PARM(ansi, "1i");462462#endif463463+464464+MODULE_LICENSE("GPL");463465#endif464466/*counter of concurrent disk read/writes, to turn on/off disk led */465467static int disk_rw_in_progress = 0;
+10
drivers/scsi/ibmvscsi/ibmvscsi.c
···727727 if (hostdata->madapter_info.port_max_txu[0]) 728728 hostdata->host->max_sectors = 729729 hostdata->madapter_info.port_max_txu[0] >> 9;730730+731731+ if (hostdata->madapter_info.os_type == 3 &&732732+ strcmp(hostdata->madapter_info.srp_version, "1.6a") <= 0) {733733+ printk("ibmvscsi: host (Ver. %s) doesn't support large"734734+ "transfers\n",735735+ hostdata->madapter_info.srp_version);736736+ printk("ibmvscsi: limiting scatterlists to %d\n",737737+ MAX_INDIRECT_BUFS);738738+ hostdata->host->sg_tablesize = MAX_INDIRECT_BUFS;739739+ }730740 }731741}732742
+49-32
drivers/scsi/libata-core.c
···41324132}4133413341344134/**41354135+ * ata_host_set_remove - PCI layer callback for device removal41364136+ * @host_set: ATA host set that was removed41374137+ *41384138+ * Unregister all objects associated with this host set. Free those 41394139+ * objects.41404140+ *41414141+ * LOCKING:41424142+ * Inherited from calling layer (may sleep).41434143+ */41444144+41454145+41464146+void ata_host_set_remove(struct ata_host_set *host_set)41474147+{41484148+ struct ata_port *ap;41494149+ unsigned int i;41504150+41514151+ for (i = 0; i < host_set->n_ports; i++) {41524152+ ap = host_set->ports[i];41534153+ scsi_remove_host(ap->host);41544154+ }41554155+41564156+ free_irq(host_set->irq, host_set);41574157+41584158+ for (i = 0; i < host_set->n_ports; i++) {41594159+ ap = host_set->ports[i];41604160+41614161+ ata_scsi_release(ap->host);41624162+41634163+ if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {41644164+ struct ata_ioports *ioaddr = &ap->ioaddr;41654165+41664166+ if (ioaddr->cmd_addr == 0x1f0)41674167+ release_region(0x1f0, 8);41684168+ else if (ioaddr->cmd_addr == 0x170)41694169+ release_region(0x170, 8);41704170+ }41714171+41724172+ scsi_host_put(ap->host);41734173+ }41744174+41754175+ if (host_set->ops->host_stop)41764176+ host_set->ops->host_stop(host_set);41774177+41784178+ kfree(host_set);41794179+}41804180+41814181+/**41354182 * ata_scsi_release - SCSI layer callback hook for host unload41364183 * @host: libata host to be unloaded41374184 *···45184471{45194472 struct device *dev = pci_dev_to_dev(pdev);45204473 struct ata_host_set *host_set = dev_get_drvdata(dev);45214521- struct ata_port *ap;45224522- unsigned int i;4523447445244524- for (i = 0; i < host_set->n_ports; i++) {45254525- ap = host_set->ports[i];45264526-45274527- scsi_remove_host(ap->host);45284528- }45294529-45304530- free_irq(host_set->irq, host_set);45314531-45324532- for (i = 0; i < host_set->n_ports; i++) {45334533- ap = host_set->ports[i];45344534-45354535- ata_scsi_release(ap->host);45364536-45374537- if ((ap->flags & ATA_FLAG_NO_LEGACY) == 0) {45384538- struct ata_ioports *ioaddr = &ap->ioaddr;45394539-45404540- if (ioaddr->cmd_addr == 0x1f0)45414541- release_region(0x1f0, 8);45424542- else if (ioaddr->cmd_addr == 0x170)45434543- release_region(0x170, 8);45444544- }45454545-45464546- scsi_host_put(ap->host);45474547- }45484548-45494549- if (host_set->ops->host_stop)45504550- host_set->ops->host_stop(host_set);45514551-45524552- kfree(host_set);45534553-44754475+ ata_host_set_remove(host_set);45544476 pci_release_regions(pdev);45554477 pci_disable_device(pdev);45564478 dev_set_drvdata(dev, NULL);···45894573EXPORT_SYMBOL_GPL(ata_std_bios_param);45904574EXPORT_SYMBOL_GPL(ata_std_ports);45914575EXPORT_SYMBOL_GPL(ata_device_add);45764576+EXPORT_SYMBOL_GPL(ata_host_set_remove);45924577EXPORT_SYMBOL_GPL(ata_sg_init);45934578EXPORT_SYMBOL_GPL(ata_sg_init_one);45944579EXPORT_SYMBOL_GPL(ata_qc_complete);
+21-8
drivers/scsi/mesh.c
···19591959 /* Set it up */19601960 mesh_init(ms);1961196119621962- /* XXX FIXME: error should be fatal */19631963- if (request_irq(ms->meshintr, do_mesh_interrupt, 0, "MESH", ms))19621962+ /* Request interrupt */19631963+ if (request_irq(ms->meshintr, do_mesh_interrupt, 0, "MESH", ms)) {19641964 printk(KERN_ERR "MESH: can't get irq %d\n", ms->meshintr);19651965+ goto out_shutdown;19661966+ }1965196719661966- /* XXX FIXME: handle failure */19671967- scsi_add_host(mesh_host, &mdev->ofdev.dev);19681968+ /* Add scsi host & scan */19691969+ if (scsi_add_host(mesh_host, &mdev->ofdev.dev))19701970+ goto out_release_irq;19681971 scsi_scan_host(mesh_host);1969197219701973 return 0;1971197419721972-out_unmap:19751975+ out_release_irq:19761976+ free_irq(ms->meshintr, ms);19771977+ out_shutdown:19781978+ /* shutdown & reset bus in case of error or macos can be confused19791979+ * at reboot if the bus was set to synchronous mode already19801980+ */19811981+ mesh_shutdown(mdev);19821982+ set_mesh_power(ms, 0);19831983+ pci_free_consistent(macio_get_pci_dev(mdev), ms->dma_cmd_size,19841984+ ms->dma_cmd_space, ms->dma_cmd_bus);19851985+ out_unmap:19731986 iounmap(ms->dma);19741987 iounmap(ms->mesh);19751975-out_free:19881988+ out_free:19761989 scsi_host_put(mesh_host);19771977-out_release:19901990+ out_release:19781991 macio_release_resources(mdev);1979199219801993 return -ENODEV;···2014200120152002 /* Free DMA commands memory */20162003 pci_free_consistent(macio_get_pci_dev(mdev), ms->dma_cmd_size,20172017- ms->dma_cmd_space, ms->dma_cmd_bus);20042004+ ms->dma_cmd_space, ms->dma_cmd_bus);2018200520192006 /* Release memory resources */20202007 macio_release_resources(mdev);
···110110 {"RELISYS", "Scorpio", NULL, BLIST_NOLUN}, /* responds to all lun */111111 {"SANKYO", "CP525", "6.64", BLIST_NOLUN}, /* causes failed REQ SENSE, extra reset */112112 {"TEXEL", "CD-ROM", "1.06", BLIST_NOLUN},113113+ {"transtec", "T5008", "0001", BLIST_NOREPORTLUN },113114 {"YAMAHA", "CDR100", "1.00", BLIST_NOLUN}, /* locks up */114115 {"YAMAHA", "CDR102", "1.00", BLIST_NOLUN}, /* locks up */115116 {"YAMAHA", "CRW8424S", "1.0", BLIST_NOLUN}, /* locks up */
+39-39
drivers/scsi/scsi_error.c
···5050void scsi_eh_wakeup(struct Scsi_Host *shost)5151{5252 if (shost->host_busy == shost->host_failed) {5353- up(shost->eh_wait);5353+ wake_up_process(shost->ehandler);5454 SCSI_LOG_ERROR_RECOVERY(5,5555 printk("Waking error handler thread\n"));5656 }···6868{6969 struct Scsi_Host *shost = scmd->device->host;7070 unsigned long flags;7171+ int ret = 0;71727272- if (shost->eh_wait == NULL)7373+ if (!shost->ehandler)7374 return 0;74757576 spin_lock_irqsave(shost->host_lock, flags);7777+ if (scsi_host_set_state(shost, SHOST_RECOVERY))7878+ if (scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY))7979+ goto out_unlock;76808181+ ret = 1;7782 scmd->eh_eflags |= eh_flag;7883 list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q);7979- scsi_host_set_state(shost, SHOST_RECOVERY);8084 shost->host_failed++;8185 scsi_eh_wakeup(shost);8686+ out_unlock:8287 spin_unlock_irqrestore(shost->host_lock, flags);8383- return 1;8888+ return ret;8489}85908691/**···181176 }182177183178 if (unlikely(!scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD))) {184184- panic("Error handler thread not present at %p %p %s %d",185185- scmd, scmd->device->host, __FILE__, __LINE__);179179+ scmd->result |= DID_TIME_OUT << 16;180180+ __scsi_done(scmd);186181 }187182}188183···201196{202197 int online;203198204204- wait_event(sdev->host->host_wait, (sdev->host->shost_state !=205205- SHOST_RECOVERY));199199+ wait_event(sdev->host->host_wait, !scsi_host_in_recovery(sdev->host));206200207201 online = scsi_device_online(sdev);208202···14451441static void scsi_restart_operations(struct Scsi_Host *shost)14461442{14471443 struct scsi_device *sdev;14441444+ unsigned long flags;1448144514491446 /*14501447 * If the door was locked, we need to insert a door lock request···14651460 SCSI_LOG_ERROR_RECOVERY(3, printk("%s: waking up host to restart\n",14661461 __FUNCTION__));1467146214681468- scsi_host_set_state(shost, SHOST_RUNNING);14631463+ spin_lock_irqsave(shost->host_lock, flags);14641464+ if (scsi_host_set_state(shost, SHOST_RUNNING))14651465+ if (scsi_host_set_state(shost, SHOST_CANCEL))14661466+ BUG_ON(scsi_host_set_state(shost, SHOST_DEL));14671467+ spin_unlock_irqrestore(shost->host_lock, flags);1469146814701469 wake_up(&shost->host_wait);14711470···15911582{15921583 struct Scsi_Host *shost = (struct Scsi_Host *) data;15931584 int rtn;15941594- DECLARE_MUTEX_LOCKED(sem);1595158515961586 current->flags |= PF_NOFREEZE;15971597- shost->eh_wait = &sem;1598158715881588+15991589 /*16001600- * Wake up the thread that created us.15901590+ * Note - we always use TASK_INTERRUPTIBLE even if the module15911591+ * was loaded as part of the kernel. The reason is that15921592+ * UNINTERRUPTIBLE would cause this thread to be counted in15931593+ * the load average as a running process, and an interruptible15941594+ * wait doesn't.16011595 */16021602- SCSI_LOG_ERROR_RECOVERY(3, printk("Wake up parent of"16031603- " scsi_eh_%d\n",shost->host_no));15961596+ set_current_state(TASK_INTERRUPTIBLE);15971597+ while (!kthread_should_stop()) {15981598+ if (shost->host_failed == 0 ||15991599+ shost->host_failed != shost->host_busy) {16001600+ SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"16011601+ " scsi_eh_%d"16021602+ " sleeping\n",16031603+ shost->host_no));16041604+ schedule();16051605+ set_current_state(TASK_INTERRUPTIBLE);16061606+ continue;16071607+ }1604160816051605- while (1) {16061606- /*16071607- * If we get a signal, it means we are supposed to go16081608- * away and die. This typically happens if the user is16091609- * trying to unload a module.16101610- */16111611- SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"16121612- " scsi_eh_%d"16131613- " sleeping\n",shost->host_no));16141614-16151615- /*16161616- * Note - we always use down_interruptible with the semaphore16171617- * even if the module was loaded as part of the kernel. The16181618- * reason is that down() will cause this thread to be counted16191619- * in the load average as a running process, and down16201620- * interruptible doesn't. Given that we need to allow this16211621- * thread to die if the driver was loaded as a module, using16221622- * semaphores isn't unreasonable.16231623- */16241624- down_interruptible(&sem);16251625- if (kthread_should_stop())16261626- break;16271627-16091609+ __set_current_state(TASK_RUNNING);16281610 SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler"16291611 " scsi_eh_%d waking"16301612 " up\n",shost->host_no));···16421642 * which are still online.16431643 */16441644 scsi_restart_operations(shost);16451645-16451645+ set_current_state(TASK_INTERRUPTIBLE);16461646 }1647164716481648 SCSI_LOG_ERROR_RECOVERY(1, printk("Error handler scsi_eh_%d"···16511651 /*16521652 * Make sure that nobody tries to wake us up again.16531653 */16541654- shost->eh_wait = NULL;16541654+ shost->ehandler = NULL;16551655 return 0;16561656}16571657
+1-1
drivers/scsi/scsi_ioctl.c
···458458 * error processing, as long as the device was opened459459 * non-blocking */460460 if (filp && filp->f_flags & O_NONBLOCK) {461461- if (sdev->host->shost_state == SHOST_RECOVERY)461461+ if (scsi_host_in_recovery(sdev->host))462462 return -ENODEV;463463 } else if (!scsi_block_when_processing_errors(sdev))464464 return -ENODEV;
+4-8
drivers/scsi/scsi_lib.c
···118118 req->flags &= ~REQ_DONTPREP;119119 req->special = (req->flags & REQ_SPECIAL) ? cmd->sc_request : NULL;120120121121- scsi_release_buffers(cmd);122121 scsi_put_command(cmd);123122}124123···139140 * commands.140141 * Notes: This could be called either from an interrupt context or a141142 * normal process context.142142- * Notes: Upon return, cmd is a stale pointer.143143 */144144int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)145145{146146 struct Scsi_Host *host = cmd->device->host;147147 struct scsi_device *device = cmd->device;148148 struct request_queue *q = device->request_queue;149149- struct request *req = cmd->request;150149 unsigned long flags;151150152151 SCSI_LOG_MLQUEUE(1,···185188 * function. The SCSI request function detects the blocked condition186189 * and plugs the queue appropriately.187190 */188188- scsi_unprep_request(req);189191 spin_lock_irqsave(q->queue_lock, flags);190190- blk_requeue_request(q, req);192192+ blk_requeue_request(q, cmd->request);191193 spin_unlock_irqrestore(q->queue_lock, flags);192194193195 scsi_run_queue(q);···447451448452 spin_lock_irqsave(shost->host_lock, flags);449453 shost->host_busy--;450450- if (unlikely((shost->shost_state == SHOST_RECOVERY) &&454454+ if (unlikely(scsi_host_in_recovery(shost) &&451455 shost->host_failed))452456 scsi_eh_wakeup(shost);453457 spin_unlock(shost->host_lock);···12641268 }12651269 } else {12661270 memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd));12711271+ cmd->cmd_len = req->cmd_len;12671272 if (rq_data_dir(req) == WRITE)12681273 cmd->sc_data_direction = DMA_TO_DEVICE;12691274 else if (req->data_len)···13391342 struct Scsi_Host *shost,13401343 struct scsi_device *sdev)13411344{13421342- if (shost->shost_state == SHOST_RECOVERY)13451345+ if (scsi_host_in_recovery(shost))13431346 return 0;13441347 if (shost->host_busy == 0 && shost->host_blocked) {13451348 /*···15111514 * cases (host limits or settings) should run the queue at some15121515 * later time.15131516 */15141514- scsi_unprep_request(req);15151517 spin_lock_irq(q->queue_lock);15161518 blk_requeue_request(q, req);15171519 sdev->device_busy--;
+7-13
drivers/scsi/scsi_scan.c
···1466146614671467void scsi_forget_host(struct Scsi_Host *shost)14681468{14691469- struct scsi_target *starget, *tmp;14691469+ struct scsi_device *sdev;14701470 unsigned long flags;1471147114721472- /*14731473- * Ok, this look a bit strange. We always look for the first device14741474- * on the list as scsi_remove_device removes them from it - thus we14751475- * also have to release the lock.14761476- * We don't need to get another reference to the device before14771477- * releasing the lock as we already own the reference from14781478- * scsi_register_device that's release in scsi_remove_device. And14791479- * after that we don't look at sdev anymore.14801480- */14721472+ restart:14811473 spin_lock_irqsave(shost->host_lock, flags);14821482- list_for_each_entry_safe(starget, tmp, &shost->__targets, siblings) {14741474+ list_for_each_entry(sdev, &shost->__devices, siblings) {14751475+ if (sdev->sdev_state == SDEV_DEL)14761476+ continue;14831477 spin_unlock_irqrestore(shost->host_lock, flags);14841484- scsi_remove_target(&starget->dev);14851485- spin_lock_irqsave(shost->host_lock, flags);14781478+ __scsi_remove_device(sdev);14791479+ goto restart;14861480 }14871481 spin_unlock_irqrestore(shost->host_lock, flags);14881482}
···235235 return 0;236236237237 memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));238238+ SCpnt->cmd_len = rq->cmd_len;238239 if (rq_data_dir(rq) == WRITE)239240 SCpnt->sc_data_direction = DMA_TO_DEVICE;240241 else if (rq->data_len)
+1-1
drivers/scsi/sg.c
···10271027 if (sdp->detached)10281028 return -ENODEV;10291029 if (filp->f_flags & O_NONBLOCK) {10301030- if (sdp->device->host->shost_state == SHOST_RECOVERY)10301030+ if (scsi_host_in_recovery(sdp->device->host))10311031 return -EBUSY;10321032 } else if (!scsi_block_when_processing_errors(sdp->device))10331033 return -EBUSY;
+1
drivers/scsi/sr.c
···326326 return 0;327327328328 memcpy(SCpnt->cmnd, rq->cmd, sizeof(SCpnt->cmnd));329329+ SCpnt->cmd_len = rq->cmd_len;329330 if (!rq->data_len)330331 SCpnt->sc_data_direction = DMA_NONE;331332 else if (rq_data_dir(rq) == WRITE)
···9898{9999 struct uart_port *port = dev_id;100100 struct tty_struct *tty = port->info->tty;101101- unsigned int status, ch, flg, ignored = 0;101101+ unsigned int status, ch, flg;102102103103 status = clps_readl(SYSFLG(port));104104 while (!(status & SYSFLG_URXFE)) {
+1-1
drivers/usb/core/message.c
···987987988988 /* remove this interface if it has been registered */989989 interface = dev->actconfig->interface[i];990990- if (!klist_node_attached(&interface->dev.knode_bus))990990+ if (!device_is_registered(&interface->dev))991991 continue;992992 dev_dbg (&dev->dev, "unregistering interface %s\n",993993 interface->dev.bus_id);
+3-3
drivers/usb/core/usb.c
···303303 /* if interface was already added, bind now; else let304304 * the future device_add() bind it, bypassing probe()305305 */306306- if (klist_node_attached(&dev->knode_bus))306306+ if (device_is_registered(dev))307307 device_bind_driver(dev);308308309309 return 0;···336336 if (iface->condition != USB_INTERFACE_BOUND)337337 return;338338339339- /* release only after device_add() */340340- if (klist_node_attached(&dev->knode_bus)) {339339+ /* don't release if the interface hasn't been added yet */340340+ if (device_is_registered(dev)) {341341 iface->condition = USB_INTERFACE_UNBINDING;342342 device_release_driver(dev);343343 }
+2-2
drivers/usb/gadget/pxa2xx_udc.c
···422422}423423424424static int425425-write_packet(volatile u32 *uddr, struct pxa2xx_request *req, unsigned max)425425+write_packet(volatile unsigned long *uddr, struct pxa2xx_request *req, unsigned max)426426{427427 u8 *buf;428428 unsigned length, count;···26022602 * VBUS IRQs should probably be ignored so that the PXA device just acts26032603 * "dead" to USB hosts until system resume.26042604 */26052605-static int pxa2xx_udc_suspend(struct device *dev, u32 state, u32 level)26052605+static int pxa2xx_udc_suspend(struct device *dev, pm_message_t state, u32 level)26062606{26072607 struct pxa2xx_udc *udc = dev_get_drvdata(dev);26082608
+4-4
drivers/usb/gadget/pxa2xx_udc.h
···6969 * UDDR = UDC Endpoint Data Register (the fifo)7070 * DRCM = DMA Request Channel Map7171 */7272- volatile u32 *reg_udccs;7373- volatile u32 *reg_ubcr;7474- volatile u32 *reg_uddr;7272+ volatile unsigned long *reg_udccs;7373+ volatile unsigned long *reg_ubcr;7474+ volatile unsigned long *reg_uddr;7575#ifdef USE_DMA7676- volatile u32 *reg_drcmr;7676+ volatile unsigned long *reg_drcmr;7777#define drcmr(n) .reg_drcmr = & DRCMR ## n ,7878#else7979#define drcmr(n)
+14-2
drivers/usb/host/sl811-hcd.c
···782782/* usb 1.1 says max 90% of a frame is available for periodic transfers.783783 * this driver doesn't promise that much since it's got to handle an784784 * IRQ per packet; irq handling latencies also use up that time.785785+ *786786+ * NOTE: the periodic schedule is a sparse tree, with the load for787787+ * each branch minimized. see fig 3.5 in the OHCI spec for example.785788 */786789#define MAX_PERIODIC_LOAD 500 /* out of 1000 usec */787790···846843 if (!(sl811->port1 & (1 << USB_PORT_FEAT_ENABLE))847844 || !HC_IS_RUNNING(hcd->state)) {848845 retval = -ENODEV;846846+ kfree(ep);849847 goto fail;850848 }851849···915911 case PIPE_ISOCHRONOUS:916912 case PIPE_INTERRUPT:917913 urb->interval = ep->period;918918- if (ep->branch < PERIODIC_SIZE)914914+ if (ep->branch < PERIODIC_SIZE) {915915+ /* NOTE: the phase is correct here, but the value916916+ * needs offsetting by the transfer queue depth.917917+ * All current drivers ignore start_frame, so this918918+ * is unlikely to ever matter...919919+ */920920+ urb->start_frame = (sl811->frame & (PERIODIC_SIZE - 1))921921+ + ep->branch;919922 break;923923+ }920924921925 retval = balance(sl811, ep->period, ep->load);922926 if (retval < 0)···11341122 desc->wHubCharacteristics = (__force __u16)cpu_to_le16(temp);1135112311361124 /* two bitmaps: ports removable, and legacy PortPwrCtrlMask */11371137- desc->bitmap[0] = 1 << 1;11251125+ desc->bitmap[0] = 0 << 1;11381126 desc->bitmap[1] = ~0;11391127}11401128
+20-9
drivers/usb/net/pegasus.c
···648648 }649649650650 /*651651+ * If the packet is unreasonably long, quietly drop it rather than652652+ * kernel panicing by calling skb_put.653653+ */654654+ if (pkt_len > PEGASUS_MTU)655655+ goto goon;656656+657657+ /*651658 * at this point we are sure pegasus->rx_skb != NULL652659 * so we go ahead and pass up the packet.653660 */···893886 __u8 data[2];894887895888 read_eprom_word(pegasus, 4, (__u16 *) data);896896- if (data[1] < 0x80) {897897- if (netif_msg_timer(pegasus))898898- dev_info(&pegasus->intf->dev,899899- "intr interval changed from %ums to %ums\n",900900- data[1], 0x80);901901- data[1] = 0x80;902902-#ifdef PEGASUS_WRITE_EEPROM903903- write_eprom_word(pegasus, 4, *(__u16 *) data);889889+ if (pegasus->usb->speed != USB_SPEED_HIGH) {890890+ if (data[1] < 0x80) {891891+ if (netif_msg_timer(pegasus))892892+ dev_info(&pegasus->intf->dev, "intr interval "893893+ "changed from %ums to %ums\n",894894+ data[1], 0x80);895895+ data[1] = 0x80;896896+#ifdef PEGASUS_WRITE_EEPROM897897+ write_eprom_word(pegasus, 4, *(__u16 *) data);904898#endif899899+ }905900 }906901 pegasus->intr_interval = data[1];907902}···913904 pegasus_t *pegasus = netdev_priv(net);914905 u16 tmp;915906916916- if (read_mii_word(pegasus, pegasus->phy, MII_BMSR, &tmp))907907+ if (!read_mii_word(pegasus, pegasus->phy, MII_BMSR, &tmp))917908 return;909909+918910 if (tmp & BMSR_LSTATUS)919911 netif_carrier_on(net);920912 else···13651355 cancel_delayed_work(&pegasus->carrier_check);13661356 unregister_netdev(pegasus->net);13671357 usb_put_dev(interface_to_usbdev(intf));13581358+ unlink_all_urbs(pegasus);13681359 free_all_urbs(pegasus);13691360 free_skb_pool(pegasus);13701361 if (pegasus->rx_skb)
···18461846 } else {18471847 /* set the baudrate determined before */18481848 if (change_speed(port)) {18491849- err("%s urb failed to set baurdrate", __FUNCTION__);18491849+ err("%s urb failed to set baudrate", __FUNCTION__);18501850 }18511851- /* Ensure RTS and DTR are raised */18521852- set_mctrl(port, TIOCM_DTR | TIOCM_RTS);18511851+ /* Ensure RTS and DTR are raised when baudrate changed from 0 */18521852+ if ((old_termios->c_cflag & CBAUD) == B0) {18531853+ set_mctrl(port, TIOCM_DTR | TIOCM_RTS);18541854+ }18531855 }1854185618551857 /* Set flow control */
···650650 select FB_CFB_FILLRECT651651 select FB_CFB_COPYAREA652652 select FB_CFB_IMAGEBLIT653653+ select FB_SOFT_CURSOR653654 help654655 This driver supports graphics boards with the nVidia chips, TNT655656 and newer. For very old chipsets, such as the RIVA128, then use
+8-3
drivers/video/aty/xlinit.c
···174174 const struct xl_card_cfg_t * card = &card_cfg[xl_card];175175 struct atyfb_par *par = (struct atyfb_par *) info->par;176176 union aty_pll pll;177177- int i, err;177177+ int err;178178 u32 temp;179179180180 aty_st_8(CONFIG_STAT0, 0x85, par);···252252 aty_st_le32(0xEC, 0x00000000, par);253253 aty_st_le32(0xFC, 0x00000000, par);254254255255- for (i=0; i<sizeof(lcd_tbl)/sizeof(lcd_tbl_t); i++) {256256- aty_st_lcd(lcd_tbl[i].lcd_reg, lcd_tbl[i].val, par);255255+#if defined (CONFIG_FB_ATY_GENERIC_LCD)256256+ {257257+ int i;258258+259259+ for (i = 0; i < ARRAY_SIZE(lcd_tbl); i++)260260+ aty_st_lcd(lcd_tbl[i].lcd_reg, lcd_tbl[i].val, par);257261 }262262+#endif258263259264 aty_st_le16(CONFIG_STAT0, 0x00A4, par);260265 mdelay(10);
···781781782782 oplockThread = current;783783 do {784784+ if (try_to_freeze()) 785785+ continue;784786 set_current_state(TASK_INTERRUPTIBLE);785787786788 schedule_timeout(1*HZ);
+2
fs/cifs/connect.c
···344344 }345345346346 while (server->tcpStatus != CifsExiting) {347347+ if (try_to_freeze())348348+ continue;347349 if (bigbuf == NULL) {348350 bigbuf = cifs_buf_get();349351 if(bigbuf == NULL) {
+2-1
fs/dcache.c
···102102 list_del_init(&dentry->d_alias);103103 spin_unlock(&dentry->d_lock);104104 spin_unlock(&dcache_lock);105105- fsnotify_inoderemove(inode);105105+ if (!inode->i_nlink)106106+ fsnotify_inoderemove(inode);106107 if (dentry->d_op && dentry->d_op->d_iput)107108 dentry->d_op->d_iput(dentry, inode);108109 else
+3-3
fs/ext3/balloc.c
···14101410 unsigned long desc_count;14111411 struct ext3_group_desc *gdp;14121412 int i;14131413- unsigned long ngroups;14131413+ unsigned long ngroups = EXT3_SB(sb)->s_groups_count;14141414#ifdef EXT3FS_DEBUG14151415 struct ext3_super_block *es;14161416 unsigned long bitmap_count, x;···14211421 desc_count = 0;14221422 bitmap_count = 0;14231423 gdp = NULL;14241424- for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {14241424+14251425+ for (i = 0; i < ngroups; i++) {14251426 gdp = ext3_get_group_desc(sb, i, NULL);14261427 if (!gdp)14271428 continue;···14441443 return bitmap_count;14451444#else14461445 desc_count = 0;14471447- ngroups = EXT3_SB(sb)->s_groups_count;14481446 smp_rmb();14491447 for (i = 0; i < ngroups; i++) {14501448 gdp = ext3_get_group_desc(sb, i, NULL);
···9292 an octal number to conform to how chmod(1) works, too. Thanks to9393 Giuseppe Bilotta and Horst von Brand for pointing out the errors of9494 my ways.9595+ - Fix various bugs in the runlist merging code. (Based on libntfs9696+ changes by Richard Russon.)959796982.1.23 - Implement extension of resident files and make writing safe as well as9799 many bug fixes, cleanups, and enhancements...
+81-39
fs/ntfs/aops.c
···5959 unsigned long flags;6060 struct buffer_head *first, *tmp;6161 struct page *page;6262+ struct inode *vi;6263 ntfs_inode *ni;6364 int page_uptodate = 1;64656566 page = bh->b_page;6666- ni = NTFS_I(page->mapping->host);6767+ vi = page->mapping->host;6868+ ni = NTFS_I(vi);67696870 if (likely(uptodate)) {6969- s64 file_ofs, initialized_size;7171+ loff_t i_size;7272+ s64 file_ofs, init_size;70737174 set_buffer_uptodate(bh);72757376 file_ofs = ((s64)page->index << PAGE_CACHE_SHIFT) +7477 bh_offset(bh);7578 read_lock_irqsave(&ni->size_lock, flags);7676- initialized_size = ni->initialized_size;7979+ init_size = ni->initialized_size;8080+ i_size = i_size_read(vi);7781 read_unlock_irqrestore(&ni->size_lock, flags);8282+ if (unlikely(init_size > i_size)) {8383+ /* Race with shrinking truncate. */8484+ init_size = i_size;8585+ }7886 /* Check for the current buffer head overflowing. */7979- if (file_ofs + bh->b_size > initialized_size) {8080- char *addr;8181- int ofs = 0;8787+ if (unlikely(file_ofs + bh->b_size > init_size)) {8888+ u8 *kaddr;8989+ int ofs;82908383- if (file_ofs < initialized_size)8484- ofs = initialized_size - file_ofs;8585- addr = kmap_atomic(page, KM_BIO_SRC_IRQ);8686- memset(addr + bh_offset(bh) + ofs, 0, bh->b_size - ofs);9191+ ofs = 0;9292+ if (file_ofs < init_size)9393+ ofs = init_size - file_ofs;9494+ kaddr = kmap_atomic(page, KM_BIO_SRC_IRQ);9595+ memset(kaddr + bh_offset(bh) + ofs, 0,9696+ bh->b_size - ofs);9797+ kunmap_atomic(kaddr, KM_BIO_SRC_IRQ);8798 flush_dcache_page(page);8888- kunmap_atomic(addr, KM_BIO_SRC_IRQ);8999 }90100 } else {91101 clear_buffer_uptodate(bh);92102 SetPageError(page);9393- ntfs_error(ni->vol->sb, "Buffer I/O error, logical block %llu.",9494- (unsigned long long)bh->b_blocknr);103103+ ntfs_error(ni->vol->sb, "Buffer I/O error, logical block "104104+ "0x%llx.", (unsigned long long)bh->b_blocknr);95105 }96106 first = page_buffers(page);97107 local_irq_save(flags);···134124 if (likely(page_uptodate && !PageError(page)))135125 SetPageUptodate(page);136126 } else {137137- char *addr;127127+ u8 *kaddr;138128 unsigned int i, recs;139129 u32 rec_size;140130···142132 recs = PAGE_CACHE_SIZE / rec_size;143133 /* Should have been verified before we got here... */144134 BUG_ON(!recs);145145- addr = kmap_atomic(page, KM_BIO_SRC_IRQ);135135+ kaddr = kmap_atomic(page, KM_BIO_SRC_IRQ);146136 for (i = 0; i < recs; i++)147147- post_read_mst_fixup((NTFS_RECORD*)(addr +137137+ post_read_mst_fixup((NTFS_RECORD*)(kaddr +148138 i * rec_size), rec_size);139139+ kunmap_atomic(kaddr, KM_BIO_SRC_IRQ);149140 flush_dcache_page(page);150150- kunmap_atomic(addr, KM_BIO_SRC_IRQ);151141 if (likely(page_uptodate && !PageError(page)))152142 SetPageUptodate(page);153143 }···178168 */179169static int ntfs_read_block(struct page *page)180170{171171+ loff_t i_size;181172 VCN vcn;182173 LCN lcn;174174+ s64 init_size;175175+ struct inode *vi;183176 ntfs_inode *ni;184177 ntfs_volume *vol;185178 runlist_element *rl;···193180 int i, nr;194181 unsigned char blocksize_bits;195182196196- ni = NTFS_I(page->mapping->host);183183+ vi = page->mapping->host;184184+ ni = NTFS_I(vi);197185 vol = ni->vol;198186199187 /* $MFT/$DATA must have its complete runlist in memory at all times. */···213199 bh = head = page_buffers(page);214200 BUG_ON(!bh);215201202202+ /*203203+ * We may be racing with truncate. To avoid some of the problems we204204+ * now take a snapshot of the various sizes and use those for the whole205205+ * of the function. In case of an extending truncate it just means we206206+ * may leave some buffers unmapped which are now allocated. This is207207+ * not a problem since these buffers will just get mapped when a write208208+ * occurs. In case of a shrinking truncate, we will detect this later209209+ * on due to the runlist being incomplete and if the page is being210210+ * fully truncated, truncate will throw it away as soon as we unlock211211+ * it so no need to worry what we do with it.212212+ */216213 iblock = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits);217214 read_lock_irqsave(&ni->size_lock, flags);218215 lblock = (ni->allocated_size + blocksize - 1) >> blocksize_bits;219219- zblock = (ni->initialized_size + blocksize - 1) >> blocksize_bits;216216+ init_size = ni->initialized_size;217217+ i_size = i_size_read(vi);220218 read_unlock_irqrestore(&ni->size_lock, flags);219219+ if (unlikely(init_size > i_size)) {220220+ /* Race with shrinking truncate. */221221+ init_size = i_size;222222+ }223223+ zblock = (init_size + blocksize - 1) >> blocksize_bits;221224222225 /* Loop through all the buffers in the page. */223226 rl = NULL;···397366 */398367static int ntfs_readpage(struct file *file, struct page *page)399368{369369+ loff_t i_size;370370+ struct inode *vi;400371 ntfs_inode *ni, *base_ni;401372 u8 *kaddr;402373 ntfs_attr_search_ctx *ctx;···417384 unlock_page(page);418385 return 0;419386 }420420- ni = NTFS_I(page->mapping->host);387387+ vi = page->mapping->host;388388+ ni = NTFS_I(vi);421389 /*422390 * Only $DATA attributes can be encrypted and only unnamed $DATA423391 * attributes can be compressed. Index root can have the flags set but424392 * this means to create compressed/encrypted files, not that the425425- * attribute is compressed/encrypted.393393+ * attribute is compressed/encrypted. Note we need to check for394394+ * AT_INDEX_ALLOCATION since this is the type of both directory and395395+ * index inodes.426396 */427427- if (ni->type != AT_INDEX_ROOT) {397397+ if (ni->type != AT_INDEX_ALLOCATION) {428398 /* If attribute is encrypted, deny access, just like NT4. */429399 if (NInoEncrypted(ni)) {430400 BUG_ON(ni->type != AT_DATA);···492456 read_lock_irqsave(&ni->size_lock, flags);493457 if (unlikely(attr_len > ni->initialized_size))494458 attr_len = ni->initialized_size;459459+ i_size = i_size_read(vi);495460 read_unlock_irqrestore(&ni->size_lock, flags);461461+ if (unlikely(attr_len > i_size)) {462462+ /* Race with shrinking truncate. */463463+ attr_len = i_size;464464+ }496465 kaddr = kmap_atomic(page, KM_USER0);497466 /* Copy the data to the page. */498467 memcpy(kaddr, (u8*)ctx->attr +···13821341 * Only $DATA attributes can be encrypted and only unnamed $DATA13831342 * attributes can be compressed. Index root can have the flags set but13841343 * this means to create compressed/encrypted files, not that the13851385- * attribute is compressed/encrypted.13441344+ * attribute is compressed/encrypted. Note we need to check for13451345+ * AT_INDEX_ALLOCATION since this is the type of both directory and13461346+ * index inodes.13861347 */13871387- if (ni->type != AT_INDEX_ROOT) {13481348+ if (ni->type != AT_INDEX_ALLOCATION) {13881349 /* If file is encrypted, deny access, just like NT4. */13891350 if (NInoEncrypted(ni)) {13901351 unlock_page(page);···14221379 unsigned int ofs = i_size & ~PAGE_CACHE_MASK;14231380 kaddr = kmap_atomic(page, KM_USER0);14241381 memset(kaddr + ofs, 0, PAGE_CACHE_SIZE - ofs);14251425- flush_dcache_page(page);14261382 kunmap_atomic(kaddr, KM_USER0);13831383+ flush_dcache_page(page);14271384 }14281385 /* Handle mst protected attributes. */14291386 if (NInoMstProtected(ni))···14861443 BUG_ON(PageWriteback(page));14871444 set_page_writeback(page);14881445 unlock_page(page);14891489- /*14901490- * Here, we do not need to zero the out of bounds area everytime14911491- * because the below memcpy() already takes care of the14921492- * mmap-at-end-of-file requirements. If the file is converted to a14931493- * non-resident one, then the code path use is switched to the14941494- * non-resident one where the zeroing happens on each ntfs_writepage()14951495- * invocation.14961496- */14971446 attr_len = le32_to_cpu(ctx->attr->data.resident.value_length);14981447 i_size = i_size_read(vi);14991448 if (unlikely(attr_len > i_size)) {14491449+ /* Race with shrinking truncate or a failed truncate. */15001450 attr_len = i_size;15011501- ctx->attr->data.resident.value_length = cpu_to_le32(attr_len);14511451+ /*14521452+ * If the truncate failed, fix it up now. If a concurrent14531453+ * truncate, we do its job, so it does not have to do anything.14541454+ */14551455+ err = ntfs_resident_attr_value_resize(ctx->mrec, ctx->attr,14561456+ attr_len);14571457+ /* Shrinking cannot fail. */14581458+ BUG_ON(err);15021459 }15031460 kaddr = kmap_atomic(page, KM_USER0);15041461 /* Copy the data from the page to the mft record. */15051462 memcpy((u8*)ctx->attr +15061463 le16_to_cpu(ctx->attr->data.resident.value_offset),15071464 kaddr, attr_len);15081508- flush_dcache_mft_record_page(ctx->ntfs_ino);15091465 /* Zero out of bounds area in the page cache page. */15101466 memset(kaddr + attr_len, 0, PAGE_CACHE_SIZE - attr_len);15111511- flush_dcache_page(page);15121467 kunmap_atomic(kaddr, KM_USER0);15131513-14681468+ flush_dcache_mft_record_page(ctx->ntfs_ino);14691469+ flush_dcache_page(page);14701470+ /* We are done with the page. */15141471 end_page_writeback(page);15151515-15161516- /* Mark the mft record dirty, so it gets written back. */14721472+ /* Finally, mark the mft record dirty, so it gets written back. */15171473 mark_mft_record_dirty(ctx->ntfs_ino);15181474 ntfs_attr_put_search_ctx(ctx);15191475 unmap_mft_record(base_ni);
+5-4
fs/ntfs/inode.c
···11661166 *11671167 * Return 0 on success and -errno on error. In the error case, the inode will11681168 * have had make_bad_inode() executed on it.11691169+ *11701170+ * Note this cannot be called for AT_INDEX_ALLOCATION.11691171 */11701172static int ntfs_read_locked_attr_inode(struct inode *base_vi, struct inode *vi)11711173{···12441242 }12451243 }12461244 /*12471247- * The encryption flag set in an index root just means to12481248- * compress all files.12451245+ * The compressed/sparse flag set in an index root just means12461246+ * to compress all files.12491247 */12501248 if (NInoMstProtected(ni) && ni->type != AT_INDEX_ROOT) {12511249 ntfs_error(vi->i_sb, "Found mst protected attribute "···13211319 "the mapping pairs array.");13221320 goto unm_err_out;13231321 }13241324- if ((NInoCompressed(ni) || NInoSparse(ni)) &&13251325- ni->type != AT_INDEX_ROOT) {13221322+ if (NInoCompressed(ni) || NInoSparse(ni)) {13261323 if (a->data.non_resident.compression_unit != 4) {13271324 ntfs_error(vi->i_sb, "Found nonstandard "13281325 "compression unit (%u instead "
+1-1
fs/ntfs/malloc.h
···11/*22 * malloc.h - NTFS kernel memory handling. Part of the Linux-NTFS project.33 *44- * Copyright (c) 2001-2004 Anton Altaparmakov44+ * Copyright (c) 2001-2005 Anton Altaparmakov55 *66 * This program/include file is free software; you can redistribute it and/or77 * modify it under the terms of the GNU General Public License as published
+92-77
fs/ntfs/runlist.c
···22 * runlist.c - NTFS runlist handling code. Part of the Linux-NTFS project.33 *44 * Copyright (c) 2001-2005 Anton Altaparmakov55- * Copyright (c) 2002 Richard Russon55+ * Copyright (c) 2002-2005 Richard Russon66 *77 * This program/include file is free software; you can redistribute it and/or88 * modify it under the terms of the GNU General Public License as published···158158 BUG_ON(!dst);159159 BUG_ON(!src);160160161161- if ((dst->lcn < 0) || (src->lcn < 0)) { /* Are we merging holes? */162162- if (dst->lcn == LCN_HOLE && src->lcn == LCN_HOLE)163163- return TRUE;161161+ /* We can merge unmapped regions even if they are misaligned. */162162+ if ((dst->lcn == LCN_RL_NOT_MAPPED) && (src->lcn == LCN_RL_NOT_MAPPED))163163+ return TRUE;164164+ /* If the runs are misaligned, we cannot merge them. */165165+ if ((dst->vcn + dst->length) != src->vcn)164166 return FALSE;165165- }166166- if ((dst->lcn + dst->length) != src->lcn) /* Are the runs contiguous? */167167- return FALSE;168168- if ((dst->vcn + dst->length) != src->vcn) /* Are the runs misaligned? */169169- return FALSE;170170-171171- return TRUE;167167+ /* If both runs are non-sparse and contiguous, we can merge them. */168168+ if ((dst->lcn >= 0) && (src->lcn >= 0) &&169169+ ((dst->lcn + dst->length) == src->lcn))170170+ return TRUE;171171+ /* If we are merging two holes, we can merge them. */172172+ if ((dst->lcn == LCN_HOLE) && (src->lcn == LCN_HOLE))173173+ return TRUE;174174+ /* Cannot merge. */175175+ return FALSE;172176}173177174178/**···218214static inline runlist_element *ntfs_rl_append(runlist_element *dst,219215 int dsize, runlist_element *src, int ssize, int loc)220216{221221- BOOL right;222222- int magic;217217+ BOOL right = FALSE; /* Right end of @src needs merging. */218218+ int marker; /* End of the inserted runs. */223219224220 BUG_ON(!dst);225221 BUG_ON(!src);226222227223 /* First, check if the right hand end needs merging. */228228- right = ntfs_are_rl_mergeable(src + ssize - 1, dst + loc + 1);224224+ if ((loc + 1) < dsize)225225+ right = ntfs_are_rl_mergeable(src + ssize - 1, dst + loc + 1);229226230227 /* Space required: @dst size + @src size, less one if we merged. */231228 dst = ntfs_rl_realloc(dst, dsize, dsize + ssize - right);···241236 if (right)242237 __ntfs_rl_merge(src + ssize - 1, dst + loc + 1);243238244244- magic = loc + ssize;239239+ /* First run after the @src runs that have been inserted. */240240+ marker = loc + ssize + 1;245241246242 /* Move the tail of @dst out of the way, then copy in @src. */247247- ntfs_rl_mm(dst, magic + 1, loc + 1 + right, dsize - loc - 1 - right);243243+ ntfs_rl_mm(dst, marker, loc + 1 + right, dsize - (loc + 1 + right));248244 ntfs_rl_mc(dst, loc + 1, src, 0, ssize);249245250246 /* Adjust the size of the preceding hole. */251247 dst[loc].length = dst[loc + 1].vcn - dst[loc].vcn;252248253249 /* We may have changed the length of the file, so fix the end marker */254254- if (dst[magic + 1].lcn == LCN_ENOENT)255255- dst[magic + 1].vcn = dst[magic].vcn + dst[magic].length;250250+ if (dst[marker].lcn == LCN_ENOENT)251251+ dst[marker].vcn = dst[marker - 1].vcn + dst[marker - 1].length;256252257253 return dst;258254}···285279static inline runlist_element *ntfs_rl_insert(runlist_element *dst,286280 int dsize, runlist_element *src, int ssize, int loc)287281{288288- BOOL left = FALSE;289289- BOOL disc = FALSE; /* Discontinuity */290290- BOOL hole = FALSE; /* Following a hole */291291- int magic;282282+ BOOL left = FALSE; /* Left end of @src needs merging. */283283+ BOOL disc = FALSE; /* Discontinuity between @dst and @src. */284284+ int marker; /* End of the inserted runs. */292285293286 BUG_ON(!dst);294287 BUG_ON(!src);295288296296- /* disc => Discontinuity between the end of @dst and the start of @src.297297- * This means we might need to insert a hole.298298- * hole => @dst ends with a hole or an unmapped region which we can299299- * extend to match the discontinuity. */289289+ /*290290+ * disc => Discontinuity between the end of @dst and the start of @src.291291+ * This means we might need to insert a "not mapped" run.292292+ */300293 if (loc == 0)301294 disc = (src[0].vcn > 0);302295 else {···308303 merged_length += src->length;309304310305 disc = (src[0].vcn > dst[loc - 1].vcn + merged_length);311311- if (disc)312312- hole = (dst[loc - 1].lcn == LCN_HOLE);313306 }314314-315315- /* Space required: @dst size + @src size, less one if we merged, plus316316- * one if there was a discontinuity, less one for a trailing hole. */317317- dst = ntfs_rl_realloc(dst, dsize, dsize + ssize - left + disc - hole);307307+ /*308308+ * Space required: @dst size + @src size, less one if we merged, plus309309+ * one if there was a discontinuity.310310+ */311311+ dst = ntfs_rl_realloc(dst, dsize, dsize + ssize - left + disc);318312 if (IS_ERR(dst))319313 return dst;320314 /*321315 * We are guaranteed to succeed from here so can start modifying the322316 * original runlist.323317 */324324-325318 if (left)326319 __ntfs_rl_merge(dst + loc - 1, src);327327-328328- magic = loc + ssize - left + disc - hole;320320+ /*321321+ * First run after the @src runs that have been inserted.322322+ * Nominally, @marker equals @loc + @ssize, i.e. location + number of323323+ * runs in @src. However, if @left, then the first run in @src has324324+ * been merged with one in @dst. And if @disc, then @dst and @src do325325+ * not meet and we need an extra run to fill the gap.326326+ */327327+ marker = loc + ssize - left + disc;329328330329 /* Move the tail of @dst out of the way, then copy in @src. */331331- ntfs_rl_mm(dst, magic, loc, dsize - loc);332332- ntfs_rl_mc(dst, loc + disc - hole, src, left, ssize - left);330330+ ntfs_rl_mm(dst, marker, loc, dsize - loc);331331+ ntfs_rl_mc(dst, loc + disc, src, left, ssize - left);333332334334- /* Adjust the VCN of the last run ... */335335- if (dst[magic].lcn <= LCN_HOLE)336336- dst[magic].vcn = dst[magic - 1].vcn + dst[magic - 1].length;333333+ /* Adjust the VCN of the first run after the insertion... */334334+ dst[marker].vcn = dst[marker - 1].vcn + dst[marker - 1].length;337335 /* ... and the length. */338338- if (dst[magic].lcn == LCN_HOLE || dst[magic].lcn == LCN_RL_NOT_MAPPED)339339- dst[magic].length = dst[magic + 1].vcn - dst[magic].vcn;336336+ if (dst[marker].lcn == LCN_HOLE || dst[marker].lcn == LCN_RL_NOT_MAPPED)337337+ dst[marker].length = dst[marker + 1].vcn - dst[marker].vcn;340338341341- /* Writing beyond the end of the file and there's a discontinuity. */339339+ /* Writing beyond the end of the file and there is a discontinuity. */342340 if (disc) {343343- if (hole)344344- dst[loc - 1].length = dst[loc].vcn - dst[loc - 1].vcn;345345- else {346346- if (loc > 0) {347347- dst[loc].vcn = dst[loc - 1].vcn +348348- dst[loc - 1].length;349349- dst[loc].length = dst[loc + 1].vcn -350350- dst[loc].vcn;351351- } else {352352- dst[loc].vcn = 0;353353- dst[loc].length = dst[loc + 1].vcn;354354- }355355- dst[loc].lcn = LCN_RL_NOT_MAPPED;341341+ if (loc > 0) {342342+ dst[loc].vcn = dst[loc - 1].vcn + dst[loc - 1].length;343343+ dst[loc].length = dst[loc + 1].vcn - dst[loc].vcn;344344+ } else {345345+ dst[loc].vcn = 0;346346+ dst[loc].length = dst[loc + 1].vcn;356347 }357357-358358- magic += hole;359359-360360- if (dst[magic].lcn == LCN_ENOENT)361361- dst[magic].vcn = dst[magic - 1].vcn +362362- dst[magic - 1].length;348348+ dst[loc].lcn = LCN_RL_NOT_MAPPED;363349 }364350 return dst;365351}···381385static inline runlist_element *ntfs_rl_replace(runlist_element *dst,382386 int dsize, runlist_element *src, int ssize, int loc)383387{384384- BOOL left = FALSE;385385- BOOL right;386386- int magic;388388+ BOOL left = FALSE; /* Left end of @src needs merging. */389389+ BOOL right = FALSE; /* Right end of @src needs merging. */390390+ int tail; /* Start of tail of @dst. */391391+ int marker; /* End of the inserted runs. */387392388393 BUG_ON(!dst);389394 BUG_ON(!src);390395391391- /* First, merge the left and right ends, if necessary. */392392- right = ntfs_are_rl_mergeable(src + ssize - 1, dst + loc + 1);396396+ /* First, see if the left and right ends need merging. */397397+ if ((loc + 1) < dsize)398398+ right = ntfs_are_rl_mergeable(src + ssize - 1, dst + loc + 1);393399 if (loc > 0)394400 left = ntfs_are_rl_mergeable(dst + loc - 1, src);395395-396396- /* Allocate some space. We'll need less if the left, right, or both397397- * ends were merged. */401401+ /*402402+ * Allocate some space. We will need less if the left, right, or both403403+ * ends get merged.404404+ */398405 dst = ntfs_rl_realloc(dst, dsize, dsize + ssize - left - right);399406 if (IS_ERR(dst))400407 return dst;···405406 * We are guaranteed to succeed from here so can start modifying the406407 * original runlists.407408 */409409+410410+ /* First, merge the left and right ends, if necessary. */408411 if (right)409412 __ntfs_rl_merge(src + ssize - 1, dst + loc + 1);410413 if (left)411414 __ntfs_rl_merge(dst + loc - 1, src);412412-413413- /* FIXME: What does this mean? (AIA) */414414- magic = loc + ssize - left;415415+ /*416416+ * Offset of the tail of @dst. This needs to be moved out of the way417417+ * to make space for the runs to be copied from @src, i.e. the first418418+ * run of the tail of @dst.419419+ * Nominally, @tail equals @loc + 1, i.e. location, skipping the420420+ * replaced run. However, if @right, then one of @dst's runs is421421+ * already merged into @src.422422+ */423423+ tail = loc + right + 1;424424+ /*425425+ * First run after the @src runs that have been inserted, i.e. where426426+ * the tail of @dst needs to be moved to.427427+ * Nominally, @marker equals @loc + @ssize, i.e. location + number of428428+ * runs in @src. However, if @left, then the first run in @src has429429+ * been merged with one in @dst.430430+ */431431+ marker = loc + ssize - left;415432416433 /* Move the tail of @dst out of the way, then copy in @src. */417417- ntfs_rl_mm(dst, magic, loc + right + 1, dsize - loc - right - 1);434434+ ntfs_rl_mm(dst, marker, tail, dsize - tail);418435 ntfs_rl_mc(dst, loc, src, left, ssize - left);419436420420- /* We may have changed the length of the file, so fix the end marker */421421- if (dst[magic].lcn == LCN_ENOENT)422422- dst[magic].vcn = dst[magic - 1].vcn + dst[magic - 1].length;437437+ /* We may have changed the length of the file, so fix the end marker. */438438+ if (dsize - tail > 0 && dst[marker].lcn == LCN_ENOENT)439439+ dst[marker].vcn = dst[marker - 1].vcn + dst[marker - 1].length;423440 return dst;424441}425442
+79-7
fs/proc/base.c
···340340 return result;341341}342342343343+344344+/* Same as proc_root_link, but this addionally tries to get fs from other345345+ * threads in the group */346346+static int proc_task_root_link(struct inode *inode, struct dentry **dentry,347347+ struct vfsmount **mnt)348348+{349349+ struct fs_struct *fs;350350+ int result = -ENOENT;351351+ struct task_struct *leader = proc_task(inode);352352+353353+ task_lock(leader);354354+ fs = leader->fs;355355+ if (fs) {356356+ atomic_inc(&fs->count);357357+ task_unlock(leader);358358+ } else {359359+ /* Try to get fs from other threads */360360+ task_unlock(leader);361361+ read_lock(&tasklist_lock);362362+ if (pid_alive(leader)) {363363+ struct task_struct *task = leader;364364+365365+ while ((task = next_thread(task)) != leader) {366366+ task_lock(task);367367+ fs = task->fs;368368+ if (fs) {369369+ atomic_inc(&fs->count);370370+ task_unlock(task);371371+ break;372372+ }373373+ task_unlock(task);374374+ }375375+ }376376+ read_unlock(&tasklist_lock);377377+ }378378+379379+ if (fs) {380380+ read_lock(&fs->lock);381381+ *mnt = mntget(fs->rootmnt);382382+ *dentry = dget(fs->root);383383+ read_unlock(&fs->lock);384384+ result = 0;385385+ put_fs_struct(fs);386386+ }387387+ return result;388388+}389389+390390+343391#define MAY_PTRACE(task) \344392 (task == current || \345393 (task->parent == current && \···519471520472/* permission checks */521473522522-static int proc_check_root(struct inode *inode)474474+/* If the process being read is separated by chroot from the reading process,475475+ * don't let the reader access the threads.476476+ */477477+static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt)523478{524524- struct dentry *de, *base, *root;525525- struct vfsmount *our_vfsmnt, *vfsmnt, *mnt;479479+ struct dentry *de, *base;480480+ struct vfsmount *our_vfsmnt, *mnt;526481 int res = 0;527527-528528- if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */529529- return -ENOENT;530482 read_lock(¤t->fs->lock);531483 our_vfsmnt = mntget(current->fs->rootmnt);532484 base = dget(current->fs->root);···559511 goto exit;560512}561513514514+static int proc_check_root(struct inode *inode)515515+{516516+ struct dentry *root;517517+ struct vfsmount *vfsmnt;518518+519519+ if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */520520+ return -ENOENT;521521+ return proc_check_chroot(root, vfsmnt);522522+}523523+562524static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)563525{564526 if (generic_permission(inode, mask, NULL) != 0)565527 return -EACCES;566528 return proc_check_root(inode);529529+}530530+531531+static int proc_task_permission(struct inode *inode, int mask, struct nameidata *nd)532532+{533533+ struct dentry *root;534534+ struct vfsmount *vfsmnt;535535+536536+ if (generic_permission(inode, mask, NULL) != 0)537537+ return -EACCES;538538+539539+ if (proc_task_root_link(inode, &root, &vfsmnt))540540+ return -ENOENT;541541+542542+ return proc_check_chroot(root, vfsmnt);567543}568544569545extern struct seq_operations proc_pid_maps_op;···1491141914921420static struct inode_operations proc_task_inode_operations = {14931421 .lookup = proc_task_lookup,14941494- .permission = proc_permission,14221422+ .permission = proc_task_permission,14951423};1496142414971425#ifdef CONFIG_SECURITY
···1414 int cmp = (encoded_op >> 24) & 15;1515 int oparg = (encoded_op << 8) >> 20;1616 int cmparg = (encoded_op << 20) >> 20;1717- int oldval = 0, ret, tem;1717+ int oldval = 0, ret;1818 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))1919 oparg = 1 << oparg;2020
+1-1
include/asm-cris/futex.h
···1414 int cmp = (encoded_op >> 24) & 15;1515 int oparg = (encoded_op << 8) >> 20;1616 int cmparg = (encoded_op << 20) >> 20;1717- int oldval = 0, ret, tem;1717+ int oldval = 0, ret;1818 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))1919 oparg = 1 << oparg;2020
+1-1
include/asm-frv/futex.h
···1414 int cmp = (encoded_op >> 24) & 15;1515 int oparg = (encoded_op << 8) >> 20;1616 int cmparg = (encoded_op << 20) >> 20;1717- int oldval = 0, ret, tem;1717+ int oldval = 0, ret;1818 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))1919 oparg = 1 << oparg;2020
+1-1
include/asm-h8300/futex.h
···1414 int cmp = (encoded_op >> 24) & 15;1515 int oparg = (encoded_op << 8) >> 20;1616 int cmparg = (encoded_op << 20) >> 20;1717- int oldval = 0, ret, tem;1717+ int oldval = 0, ret;1818 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))1919 oparg = 1 << oparg;2020
+1-1
include/asm-i386/futex.h
···6161 if (op == FUTEX_OP_SET)6262 __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg);6363 else {6464-#ifndef CONFIG_X86_BSWAP6464+#if !defined(CONFIG_X86_BSWAP) && !defined(CONFIG_UML)6565 if (boot_cpu_data.x86 == 3)6666 ret = -ENOSYS;6767 else
+1-1
include/asm-ia64/futex.h
···1414 int cmp = (encoded_op >> 24) & 15;1515 int oparg = (encoded_op << 8) >> 20;1616 int cmparg = (encoded_op << 20) >> 20;1717- int oldval = 0, ret, tem;1717+ int oldval = 0, ret;1818 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))1919 oparg = 1 << oparg;2020
+5
include/asm-ia64/mca.h
···8080 u64 sal_ra; /* Return address in SAL, physical */8181 u64 sal_gp; /* GP of the SAL - physical */8282 pal_min_state_area_t *pal_min_state; /* from R17. physical in asm, virtual in C */8383+ /* Previous values of IA64_KR(CURRENT) and IA64_KR(CURRENT_STACK).8484+ * Note: if the MCA/INIT recovery code wants to resume to a new context8585+ * then it must change these values to reflect the new kernel stack.8686+ */8387 u64 prev_IA64_KR_CURRENT; /* previous value of IA64_KR(CURRENT) */8888+ u64 prev_IA64_KR_CURRENT_STACK;8489 struct task_struct *prev_task; /* previous task, NULL if it is not useful */8590 /* Some interrupt registers are not saved in minstate, pt_regs or8691 * switch_stack. Because MCA/INIT can occur when interrupts are
+1-1
include/asm-m32r/futex.h
···1414 int cmp = (encoded_op >> 24) & 15;1515 int oparg = (encoded_op << 8) >> 20;1616 int cmparg = (encoded_op << 20) >> 20;1717- int oldval = 0, ret, tem;1717+ int oldval = 0, ret;1818 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))1919 oparg = 1 << oparg;2020
+1-1
include/asm-m68k/futex.h
···1414 int cmp = (encoded_op >> 24) & 15;1515 int oparg = (encoded_op << 8) >> 20;1616 int cmparg = (encoded_op << 20) >> 20;1717- int oldval = 0, ret, tem;1717+ int oldval = 0, ret;1818 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))1919 oparg = 1 << oparg;2020
+1-1
include/asm-m68knommu/futex.h
···1414 int cmp = (encoded_op >> 24) & 15;1515 int oparg = (encoded_op << 8) >> 20;1616 int cmparg = (encoded_op << 20) >> 20;1717- int oldval = 0, ret, tem;1717+ int oldval = 0, ret;1818 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))1919 oparg = 1 << oparg;2020
+1-1
include/asm-parisc/futex.h
···1414 int cmp = (encoded_op >> 24) & 15;1515 int oparg = (encoded_op << 8) >> 20;1616 int cmparg = (encoded_op << 20) >> 20;1717- int oldval = 0, ret, tem;1717+ int oldval = 0, ret;1818 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))1919 oparg = 1 << oparg;2020
+1-1
include/asm-ppc/futex.h
···1414 int cmp = (encoded_op >> 24) & 15;1515 int oparg = (encoded_op << 8) >> 20;1616 int cmparg = (encoded_op << 20) >> 20;1717- int oldval = 0, ret, tem;1717+ int oldval = 0, ret;1818 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))1919 oparg = 1 << oparg;2020
···11+#ifndef _SMU_H22+#define _SMU_H33+14/*25 * Definitions for talking to the SMU chip in newer G5 PowerMacs36 */4758#include <linux/config.h>99+#include <linux/list.h>610711/*88- * Basic routines for use by architecture. To be extended as99- * we understand more of the chip1212+ * Known SMU commands1313+ *1414+ * Most of what is below comes from looking at the Open Firmware driver,1515+ * though this is still incomplete and could use better documentation here1616+ * or there...1717+ */1818+1919+2020+/*2121+ * Partition info commands2222+ *2323+ * I do not know what those are for at this point2424+ */2525+#define SMU_CMD_PARTITION_COMMAND 0x3e2626+2727+2828+/*2929+ * Fan control3030+ *3131+ * This is a "mux" for fan control commands, first byte is the3232+ * "sub" command.3333+ */3434+#define SMU_CMD_FAN_COMMAND 0x4a3535+3636+3737+/*3838+ * Battery access3939+ *4040+ * Same command number as the PMU, could it be same syntax ?4141+ */4242+#define SMU_CMD_BATTERY_COMMAND 0x6f4343+#define SMU_CMD_GET_BATTERY_INFO 0x004444+4545+/*4646+ * Real time clock control4747+ *4848+ * This is a "mux", first data byte contains the "sub" command.4949+ * The "RTC" part of the SMU controls the date, time, powerup5050+ * timer, but also a PRAM5151+ *5252+ * Dates are in BCD format on 7 bytes:5353+ * [sec] [min] [hour] [weekday] [month day] [month] [year]5454+ * with month being 1 based and year minus 1005555+ */5656+#define SMU_CMD_RTC_COMMAND 0x8e5757+#define SMU_CMD_RTC_SET_PWRUP_TIMER 0x00 /* i: 7 bytes date */5858+#define SMU_CMD_RTC_GET_PWRUP_TIMER 0x01 /* o: 7 bytes date */5959+#define SMU_CMD_RTC_STOP_PWRUP_TIMER 0x026060+#define SMU_CMD_RTC_SET_PRAM_BYTE_ACC 0x20 /* i: 1 byte (address?) */6161+#define SMU_CMD_RTC_SET_PRAM_AUTOINC 0x21 /* i: 1 byte (data?) */6262+#define SMU_CMD_RTC_SET_PRAM_LO_BYTES 0x22 /* i: 10 bytes */6363+#define SMU_CMD_RTC_SET_PRAM_HI_BYTES 0x23 /* i: 10 bytes */6464+#define SMU_CMD_RTC_GET_PRAM_BYTE 0x28 /* i: 1 bytes (address?) */6565+#define SMU_CMD_RTC_GET_PRAM_LO_BYTES 0x29 /* o: 10 bytes */6666+#define SMU_CMD_RTC_GET_PRAM_HI_BYTES 0x2a /* o: 10 bytes */6767+#define SMU_CMD_RTC_SET_DATETIME 0x80 /* i: 7 bytes date */6868+#define SMU_CMD_RTC_GET_DATETIME 0x81 /* o: 7 bytes date */6969+7070+ /*7171+ * i2c commands7272+ *7373+ * To issue an i2c command, first is to send a parameter block to the7474+ * the SMU. This is a command of type 0x9a with 9 bytes of header7575+ * eventually followed by data for a write:7676+ *7777+ * 0: bus number (from device-tree usually, SMU has lots of busses !)7878+ * 1: transfer type/format (see below)7979+ * 2: device address. For combined and combined4 type transfers, this8080+ * is the "write" version of the address (bit 0x01 cleared)8181+ * 3: subaddress length (0..3)8282+ * 4: subaddress byte 0 (or only byte for subaddress length 1)8383+ * 5: subaddress byte 18484+ * 6: subaddress byte 28585+ * 7: combined address (device address for combined mode data phase)8686+ * 8: data length8787+ *8888+ * The transfer types are the same good old Apple ones it seems,8989+ * that is:9090+ * - 0x00: Simple transfer9191+ * - 0x01: Subaddress transfer (addr write + data tx, no restart)9292+ * - 0x02: Combined transfer (addr write + restart + data tx)9393+ *9494+ * This is then followed by actual data for a write.9595+ *9696+ * At this point, the OF driver seems to have a limitation on transfer9797+ * sizes of 0xd bytes on reads and 0x5 bytes on writes. I do not know9898+ * wether this is just an OF limit due to some temporary buffer size9999+ * or if this is an SMU imposed limit. This driver has the same limitation100100+ * for now as I use a 0x10 bytes temporary buffer as well101101+ *102102+ * Once that is completed, a response is expected from the SMU. This is103103+ * obtained via a command of type 0x9a with a length of 1 byte containing104104+ * 0 as the data byte. OF also fills the rest of the data buffer with 0xff's105105+ * though I can't tell yet if this is actually necessary. Once this command106106+ * is complete, at this point, all I can tell is what OF does. OF tests107107+ * byte 0 of the reply:108108+ * - on read, 0xfe or 0xfc : bus is busy, wait (see below) or nak ?109109+ * - on read, 0x00 or 0x01 : reply is in buffer (after the byte 0)110110+ * - on write, < 0 -> failure (immediate exit)111111+ * - else, OF just exists (without error, weird)112112+ *113113+ * So on read, there is this wait-for-busy thing when getting a 0xfc or114114+ * 0xfe result. OF does a loop of up to 64 retries, waiting 20ms and115115+ * doing the above again until either the retries expire or the result116116+ * is no longer 0xfe or 0xfc117117+ *118118+ * The Darwin I2C driver is less subtle though. On any non-success status119119+ * from the response command, it waits 5ms and tries again up to 20 times,120120+ * it doesn't differenciate between fatal errors or "busy" status.121121+ *122122+ * This driver provides an asynchronous paramblock based i2c command123123+ * interface to be used either directly by low level code or by a higher124124+ * level driver interfacing to the linux i2c layer. The current125125+ * implementation of this relies on working timers & timer interrupts126126+ * though, so be careful of calling context for now. This may be "fixed"127127+ * in the future by adding a polling facility.128128+ */129129+#define SMU_CMD_I2C_COMMAND 0x9a130130+ /* transfer types */131131+#define SMU_I2C_TRANSFER_SIMPLE 0x00132132+#define SMU_I2C_TRANSFER_STDSUB 0x01133133+#define SMU_I2C_TRANSFER_COMBINED 0x02134134+135135+/*136136+ * Power supply control137137+ *138138+ * The "sub" command is an ASCII string in the data, the139139+ * data lenght is that of the string.140140+ *141141+ * The VSLEW command can be used to get or set the voltage slewing.142142+ * - lenght 5 (only "VSLEW") : it returns "DONE" and 3 bytes of143143+ * reply at data offset 6, 7 and 8.144144+ * - lenght 8 ("VSLEWxyz") has 3 additional bytes appended, and is145145+ * used to set the voltage slewing point. The SMU replies with "DONE"146146+ * I yet have to figure out their exact meaning of those 3 bytes in147147+ * both cases.148148+ *149149+ */150150+#define SMU_CMD_POWER_COMMAND 0xaa151151+#define SMU_CMD_POWER_RESTART "RESTART"152152+#define SMU_CMD_POWER_SHUTDOWN "SHUTDOWN"153153+#define SMU_CMD_POWER_VOLTAGE_SLEW "VSLEW"154154+155155+/* Misc commands156156+ *157157+ * This command seem to be a grab bag of various things158158+ */159159+#define SMU_CMD_MISC_df_COMMAND 0xdf160160+#define SMU_CMD_MISC_df_SET_DISPLAY_LIT 0x02 /* i: 1 byte */161161+#define SMU_CMD_MISC_df_NMI_OPTION 0x04162162+163163+/*164164+ * Version info commands165165+ *166166+ * I haven't quite tried to figure out how these work167167+ */168168+#define SMU_CMD_VERSION_COMMAND 0xea169169+170170+171171+/*172172+ * Misc commands173173+ *174174+ * This command seem to be a grab bag of various things175175+ */176176+#define SMU_CMD_MISC_ee_COMMAND 0xee177177+#define SMU_CMD_MISC_ee_GET_DATABLOCK_REC 0x02178178+#define SMU_CMD_MISC_ee_LEDS_CTRL 0x04 /* i: 00 (00,01) [00] */179179+#define SMU_CMD_MISC_ee_GET_DATA 0x05 /* i: 00 , o: ?? */180180+181181+182182+183183+/*184184+ * - Kernel side interface -185185+ */186186+187187+#ifdef __KERNEL__188188+189189+/*190190+ * Asynchronous SMU commands191191+ *192192+ * Fill up this structure and submit it via smu_queue_command(),193193+ * and get notified by the optional done() callback, or because194194+ * status becomes != 1195195+ */196196+197197+struct smu_cmd;198198+199199+struct smu_cmd200200+{201201+ /* public */202202+ u8 cmd; /* command */203203+ int data_len; /* data len */204204+ int reply_len; /* reply len */205205+ void *data_buf; /* data buffer */206206+ void *reply_buf; /* reply buffer */207207+ int status; /* command status */208208+ void (*done)(struct smu_cmd *cmd, void *misc);209209+ void *misc;210210+211211+ /* private */212212+ struct list_head link;213213+};214214+215215+/*216216+ * Queues an SMU command, all fields have to be initialized217217+ */218218+extern int smu_queue_cmd(struct smu_cmd *cmd);219219+220220+/*221221+ * Simple command wrapper. This structure embeds a small buffer222222+ * to ease sending simple SMU commands from the stack223223+ */224224+struct smu_simple_cmd225225+{226226+ struct smu_cmd cmd;227227+ u8 buffer[16];228228+};229229+230230+/*231231+ * Queues a simple command. All fields will be initialized by that232232+ * function233233+ */234234+extern int smu_queue_simple(struct smu_simple_cmd *scmd, u8 command,235235+ unsigned int data_len,236236+ void (*done)(struct smu_cmd *cmd, void *misc),237237+ void *misc,238238+ ...);239239+240240+/*241241+ * Completion helper. Pass it to smu_queue_simple or as 'done'242242+ * member to smu_queue_cmd, it will call complete() on the struct243243+ * completion passed in the "misc" argument244244+ */245245+extern void smu_done_complete(struct smu_cmd *cmd, void *misc);246246+247247+/*248248+ * Synchronous helpers. Will spin-wait for completion of a command249249+ */250250+extern void smu_spinwait_cmd(struct smu_cmd *cmd);251251+252252+static inline void smu_spinwait_simple(struct smu_simple_cmd *scmd)253253+{254254+ smu_spinwait_cmd(&scmd->cmd);255255+}256256+257257+/*258258+ * Poll routine to call if blocked with irqs off259259+ */260260+extern void smu_poll(void);261261+262262+263263+/*264264+ * Init routine, presence check....10265 */11266extern int smu_init(void);12267extern int smu_present(void);268268+struct of_device;269269+extern struct of_device *smu_get_ofdev(void);270270+271271+272272+/*273273+ * Common command wrappers274274+ */13275extern void smu_shutdown(void);14276extern void smu_restart(void);1515-extern int smu_get_rtc_time(struct rtc_time *time);1616-extern int smu_set_rtc_time(struct rtc_time *time);277277+struct rtc_time;278278+extern int smu_get_rtc_time(struct rtc_time *time, int spinwait);279279+extern int smu_set_rtc_time(struct rtc_time *time, int spinwait);1728018281/*19282 * SMU command buffer absolute address, exported by pmac_setup,20283 * this is allocated very early during boot.21284 */22285extern unsigned long smu_cmdbuf_abs;286286+287287+288288+/*289289+ * Kenrel asynchronous i2c interface290290+ */291291+292292+/* SMU i2c header, exactly matches i2c header on wire */293293+struct smu_i2c_param294294+{295295+ u8 bus; /* SMU bus ID (from device tree) */296296+ u8 type; /* i2c transfer type */297297+ u8 devaddr; /* device address (includes direction) */298298+ u8 sublen; /* subaddress length */299299+ u8 subaddr[3]; /* subaddress */300300+ u8 caddr; /* combined address, filled by SMU driver */301301+ u8 datalen; /* length of transfer */302302+ u8 data[7]; /* data */303303+};304304+305305+#define SMU_I2C_READ_MAX 0x0d306306+#define SMU_I2C_WRITE_MAX 0x05307307+308308+struct smu_i2c_cmd309309+{310310+ /* public */311311+ struct smu_i2c_param info;312312+ void (*done)(struct smu_i2c_cmd *cmd, void *misc);313313+ void *misc;314314+ int status; /* 1 = pending, 0 = ok, <0 = fail */315315+316316+ /* private */317317+ struct smu_cmd scmd;318318+ int read;319319+ int stage;320320+ int retries;321321+ u8 pdata[0x10];322322+ struct list_head link;323323+};324324+325325+/*326326+ * Call this to queue an i2c command to the SMU. You must fill info,327327+ * including info.data for a write, done and misc.328328+ * For now, no polling interface is provided so you have to use completion329329+ * callback.330330+ */331331+extern int smu_queue_i2c(struct smu_i2c_cmd *cmd);332332+333333+334334+#endif /* __KERNEL__ */335335+336336+/*337337+ * - Userland interface -338338+ */339339+340340+/*341341+ * A given instance of the device can be configured for 2 different342342+ * things at the moment:343343+ *344344+ * - sending SMU commands (default at open() time)345345+ * - receiving SMU events (not yet implemented)346346+ *347347+ * Commands are written with write() of a command block. They can be348348+ * "driver" commands (for example to switch to event reception mode)349349+ * or real SMU commands. They are made of a header followed by command350350+ * data if any.351351+ *352352+ * For SMU commands (not for driver commands), you can then read() back353353+ * a reply. The reader will be blocked or not depending on how the device354354+ * file is opened. poll() isn't implemented yet. The reply will consist355355+ * of a header as well, followed by the reply data if any. You should356356+ * always provide a buffer large enough for the maximum reply data, I357357+ * recommand one page.358358+ *359359+ * It is illegal to send SMU commands through a file descriptor configured360360+ * for events reception361361+ *362362+ */363363+struct smu_user_cmd_hdr364364+{365365+ __u32 cmdtype;366366+#define SMU_CMDTYPE_SMU 0 /* SMU command */367367+#define SMU_CMDTYPE_WANTS_EVENTS 1 /* switch fd to events mode */368368+369369+ __u8 cmd; /* SMU command byte */370370+ __u32 data_len; /* Lenght of data following */371371+};372372+373373+struct smu_user_reply_hdr374374+{375375+ __u32 status; /* Command status */376376+ __u32 reply_len; /* Lenght of data follwing */377377+};378378+379379+#endif /* _SMU_H */
+1-1
include/asm-s390/futex.h
···1414 int cmp = (encoded_op >> 24) & 15;1515 int oparg = (encoded_op << 8) >> 20;1616 int cmparg = (encoded_op << 20) >> 20;1717- int oldval = 0, ret, tem;1717+ int oldval = 0, ret;1818 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))1919 oparg = 1 << oparg;2020
+1-1
include/asm-sh/futex.h
···1414 int cmp = (encoded_op >> 24) & 15;1515 int oparg = (encoded_op << 8) >> 20;1616 int cmparg = (encoded_op << 20) >> 20;1717- int oldval = 0, ret, tem;1717+ int oldval = 0, ret;1818 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))1919 oparg = 1 << oparg;2020
+1-1
include/asm-sh64/futex.h
···1414 int cmp = (encoded_op >> 24) & 15;1515 int oparg = (encoded_op << 8) >> 20;1616 int cmparg = (encoded_op << 20) >> 20;1717- int oldval = 0, ret, tem;1717+ int oldval = 0, ret;1818 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))1919 oparg = 1 << oparg;2020
+1-1
include/asm-sparc/futex.h
···1414 int cmp = (encoded_op >> 24) & 15;1515 int oparg = (encoded_op << 8) >> 20;1616 int cmparg = (encoded_op << 20) >> 20;1717- int oldval = 0, ret, tem;1717+ int oldval = 0, ret;1818 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))1919 oparg = 1 << oparg;2020
-7
include/asm-sparc64/cacheflush.h
···44#include <linux/config.h>55#include <asm/page.h>6677-/* Flushing for D-cache alias handling is only needed if88- * the page size is smaller than 16K.99- */1010-#if PAGE_SHIFT < 141111-#define DCACHE_ALIASING_POSSIBLE1212-#endif1313-147#ifndef __ASSEMBLY__158169#include <linux/mm.h>
+1-1
include/asm-sparc64/futex.h
···1414 int cmp = (encoded_op >> 24) & 15;1515 int oparg = (encoded_op << 8) >> 20;1616 int cmparg = (encoded_op << 20) >> 20;1717- int oldval = 0, ret, tem;1717+ int oldval = 0, ret;1818 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))1919 oparg = 1 << oparg;2020
···2121#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)2222#define PAGE_MASK (~(PAGE_SIZE-1))23232424+/* Flushing for D-cache alias handling is only needed if2525+ * the page size is smaller than 16K.2626+ */2727+#if PAGE_SHIFT < 142828+#define DCACHE_ALIASING_POSSIBLE2929+#endif3030+2431#ifdef __KERNEL__25322633#ifndef __ASSEMBLY__
···2424#include <asm/processor.h>2525#include <asm/const.h>26262727-/* The kernel image occupies 0x4000000 to 0x1000000 (4MB --> 16MB).2828- * The page copy blockops use 0x1000000 to 0x18000000 (16MB --> 24MB).2727+/* The kernel image occupies 0x4000000 to 0x1000000 (4MB --> 32MB).2828+ * The page copy blockops can use 0x2000000 to 0x10000000.2929 * The PROM resides in an area spanning 0xf0000000 to 0x100000000.3030- * The vmalloc area spans 0x140000000 to 0x200000000.3030+ * The vmalloc area spans 0x100000000 to 0x200000000.3131+ * Since modules need to be in the lowest 32-bits of the address space,3232+ * we place them right before the OBP area from 0x10000000 to 0xf0000000.3133 * There is a single static kernel PMD which maps from 0x0 to address3234 * 0x400000000.3335 */3434-#define TLBTEMP_BASE _AC(0x0000000001000000,UL)3535-#define MODULES_VADDR _AC(0x0000000002000000,UL)3636-#define MODULES_LEN _AC(0x000000007e000000,UL)3737-#define MODULES_END _AC(0x0000000080000000,UL)3838-#define VMALLOC_START _AC(0x0000000140000000,UL)3939-#define VMALLOC_END _AC(0x0000000200000000,UL)3636+#define TLBTEMP_BASE _AC(0x0000000002000000,UL)3737+#define MODULES_VADDR _AC(0x0000000010000000,UL)3838+#define MODULES_LEN _AC(0x00000000e0000000,UL)3939+#define MODULES_END _AC(0x00000000f0000000,UL)4040#define LOW_OBP_ADDRESS _AC(0x00000000f0000000,UL)4141#define HI_OBP_ADDRESS _AC(0x0000000100000000,UL)4242+#define VMALLOC_START _AC(0x0000000100000000,UL)4343+#define VMALLOC_END _AC(0x0000000200000000,UL)42444345/* XXX All of this needs to be rethought so we can take advantage4446 * XXX cheetah's full 64-bit virtual address space, ie. no more hole
+5-46
include/asm-um/futex.h
···11-#ifndef _ASM_FUTEX_H22-#define _ASM_FUTEX_H33-44-#ifdef __KERNEL__11+#ifndef __UM_FUTEX_H22+#define __UM_FUTEX_H5364#include <linux/futex.h>75#include <asm/errno.h>66+#include <asm/system.h>77+#include <asm/processor.h>88#include <asm/uaccess.h>991010-static inline int1111-futex_atomic_op_inuser (int encoded_op, int __user *uaddr)1212-{1313- int op = (encoded_op >> 28) & 7;1414- int cmp = (encoded_op >> 24) & 15;1515- int oparg = (encoded_op << 8) >> 20;1616- int cmparg = (encoded_op << 20) >> 20;1717- int oldval = 0, ret, tem;1818- if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))1919- oparg = 1 << oparg;1010+#include "asm/arch/futex.h"20112121- if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int)))2222- return -EFAULT;2323-2424- inc_preempt_count();2525-2626- switch (op) {2727- case FUTEX_OP_SET:2828- case FUTEX_OP_ADD:2929- case FUTEX_OP_OR:3030- case FUTEX_OP_ANDN:3131- case FUTEX_OP_XOR:3232- default:3333- ret = -ENOSYS;3434- }3535-3636- dec_preempt_count();3737-3838- if (!ret) {3939- switch (cmp) {4040- case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break;4141- case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break;4242- case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break;4343- case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break;4444- case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break;4545- case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break;4646- default: ret = -ENOSYS;4747- }4848- }4949- return ret;5050-}5151-5252-#endif5312#endif
···1414 int cmp = (encoded_op >> 24) & 15;1515 int oparg = (encoded_op << 8) >> 20;1616 int cmparg = (encoded_op << 20) >> 20;1717- int oldval = 0, ret, tem;1717+ int oldval = 0, ret;1818 if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28))1919 oparg = 1 << oparg;2020
+1-1
include/asm-xtensa/atomic.h
···2222#include <asm/processor.h>2323#include <asm/system.h>24242525-#define ATOMIC_INIT(i) ( (atomic_t) { (i) } )2525+#define ATOMIC_INIT(i) { (i) }26262727/*2828 * This Xtensa implementation assumes that the right mechanism
+1-1
include/asm-xtensa/bitops.h
···174174 return 1UL & (((const volatile unsigned int *)addr)[nr>>5] >> (nr&31));175175}176176177177-#if XCHAL_HAVE_NSAU177177+#if XCHAL_HAVE_NSA178178179179static __inline__ int __cntlz (unsigned long x)180180{
+1
include/asm-xtensa/hardirq.h
···2323 unsigned int __nmi_count; /* arch dependent */2424} ____cacheline_aligned irq_cpustat_t;25252626+void ack_bad_irq(unsigned int irq);2627#include <linux/irq_cpustat.h> /* Standard mappings for irq_cpustat_t above */27282829#endif /* _XTENSA_HARDIRQ_H */
+11-38
include/asm-xtensa/semaphore.h
···2020 atomic_t count;2121 int sleepers;2222 wait_queue_head_t wait;2323-#if WAITQUEUE_DEBUG2424- long __magic;2525-#endif2623};27242828-#if WAITQUEUE_DEBUG2929-# define __SEM_DEBUG_INIT(name) \3030- , (int)&(name).__magic3131-#else3232-# define __SEM_DEBUG_INIT(name)3333-#endif2525+#define __SEMAPHORE_INITIALIZER(name,n) \2626+{ \2727+ .count = ATOMIC_INIT(n), \2828+ .sleepers = 0, \2929+ .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \3030+}34313535-#define __SEMAPHORE_INITIALIZER(name,count) \3636- { ATOMIC_INIT(count), \3737- 0, \3838- __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \3939- __SEM_DEBUG_INIT(name) }4040-4141-#define __MUTEX_INITIALIZER(name) \3232+#define __MUTEX_INITIALIZER(name) \4233 __SEMAPHORE_INITIALIZER(name, 1)43344444-#define __DECLARE_SEMAPHORE_GENERIC(name,count) \3535+#define __DECLARE_SEMAPHORE_GENERIC(name,count) \4536 struct semaphore name = __SEMAPHORE_INITIALIZER(name,count)46374738#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1)···40494150static inline void sema_init (struct semaphore *sem, int val)4251{4343-/*4444- * *sem = (struct semaphore)__SEMAPHORE_INITIALIZER((*sem),val);4545- *4646- * i'd rather use the more flexible initialization above, but sadly4747- * GCC 2.7.2.3 emits a bogus warning. EGCS doesnt. Oh well.4848- */4952 atomic_set(&sem->count, val);5053 init_waitqueue_head(&sem->wait);5151-#if WAITQUEUE_DEBUG5252- sem->__magic = (int)&sem->__magic;5353-#endif5454}55555656static inline void init_MUTEX (struct semaphore *sem)···63816482static inline void down(struct semaphore * sem)6583{6666-#if WAITQUEUE_DEBUG6767- CHECK_MAGIC(sem->__magic);6868-#endif8484+ might_sleep();69857086 if (atomic_sub_return(1, &sem->count) < 0)7187 __down(sem);···7292static inline int down_interruptible(struct semaphore * sem)7393{7494 int ret = 0;7575-#if WAITQUEUE_DEBUG7676- CHECK_MAGIC(sem->__magic);7777-#endif9595+9696+ might_sleep();78977998 if (atomic_sub_return(1, &sem->count) < 0)8099 ret = __down_interruptible(sem);···83104static inline int down_trylock(struct semaphore * sem)84105{85106 int ret = 0;8686-#if WAITQUEUE_DEBUG8787- CHECK_MAGIC(sem->__magic);8888-#endif8910790108 if (atomic_sub_return(1, &sem->count) < 0)91109 ret = __down_trylock(sem);···95119 */96120static inline void up(struct semaphore * sem)97121{9898-#if WAITQUEUE_DEBUG9999- CHECK_MAGIC(sem->__magic);100100-#endif101122 if (atomic_add_return(1, &sem->count) <= 0)102123 __up(sem);103124}
-16
include/asm-xtensa/system.h
···189189190190#define tas(ptr) (xchg((ptr),1))191191192192-#if ( __XCC__ == 1 )193193-194194-/* xt-xcc processes __inline__ differently than xt-gcc and decides to195195- * insert an out-of-line copy of function __xchg. This presents the196196- * unresolved symbol at link time of __xchg_called_with_bad_pointer,197197- * even though such a function would never be called at run-time.198198- * xt-gcc always inlines __xchg, and optimizes away the undefined199199- * bad_pointer function.200200- */201201-202202-#define xchg(ptr,x) xchg_u32(ptr,x)203203-204204-#else /* assume xt-gcc */205205-206192#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))207193208194/*···209223 __xchg_called_with_bad_pointer();210224 return x;211225}212212-213213-#endif214226215227extern void set_except_vector(int n, void *addr);216228
+4
include/linux/byteorder/generic.h
···55 * linux/byteorder_generic.h66 * Generic Byte-reordering support77 *88+ * The "... p" macros, like le64_to_cpup, can be used with pointers99+ * to unaligned data, but there will be a performance penalty on 1010+ * some architectures. Use get_unaligned for unaligned data.1111+ *812 * Francois-Rene Rideau <fare@tunes.org> 19970707913 * gathered all the good ideas from all asm-foo/byteorder.h into one file,1014 * cleaned them up.
+5
include/linux/device.h
···317317 dev->driver_data = data;318318}319319320320+static inline int device_is_registered(struct device *dev)321321+{322322+ return klist_node_attached(&dev->knode_bus);323323+}324324+320325/*321326 * High level routines for use by the bus drivers322327 */
+4-4
include/linux/if_vlan.h
···4242struct vlan_ethhdr {4343 unsigned char h_dest[ETH_ALEN]; /* destination eth addr */4444 unsigned char h_source[ETH_ALEN]; /* source ether addr */4545- unsigned short h_vlan_proto; /* Should always be 0x8100 */4646- unsigned short h_vlan_TCI; /* Encapsulates priority and VLAN ID */4545+ __be16 h_vlan_proto; /* Should always be 0x8100 */4646+ __be16 h_vlan_TCI; /* Encapsulates priority and VLAN ID */4747 unsigned short h_vlan_encapsulated_proto; /* packet type ID field (or len) */4848};4949···5555}56565757struct vlan_hdr {5858- unsigned short h_vlan_TCI; /* Encapsulates priority and VLAN ID */5959- unsigned short h_vlan_encapsulated_proto; /* packet type ID field (or len) */5858+ __be16 h_vlan_TCI; /* Encapsulates priority and VLAN ID */5959+ __be16 h_vlan_encapsulated_proto; /* packet type ID field (or len) */6060};61616262#define VLAN_VID_MASK 0xfff
+1
include/linux/libata.h
···393393extern void ata_pci_remove_one (struct pci_dev *pdev);394394#endif /* CONFIG_PCI */395395extern int ata_device_add(struct ata_probe_ent *ent);396396+extern void ata_host_set_remove(struct ata_host_set *host_set);396397extern int ata_scsi_detect(Scsi_Host_Template *sht);397398extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);398399extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
+5-5
include/linux/mm.h
···136136#define VM_EXEC 0x00000004137137#define VM_SHARED 0x00000008138138139139+/* mprotect() hardcodes VM_MAYREAD >> 4 == VM_READ, and so for r/w/x bits. */139140#define VM_MAYREAD 0x00000010 /* limits for mprotect() etc */140141#define VM_MAYWRITE 0x00000020141142#define VM_MAYEXEC 0x00000040···351350 * only one copy in memory, at most, normally.352351 *353352 * For the non-reserved pages, page_count(page) denotes a reference count.354354- * page_count() == 0 means the page is free.353353+ * page_count() == 0 means the page is free. page->lru is then used for354354+ * freelist management in the buddy allocator.355355 * page_count() == 1 means the page is used for exactly one purpose356356 * (e.g. a private data page of one process).357357 *···378376 * attaches, plus 1 if `private' contains something, plus one for379377 * the page cache itself.380378 *381381- * All pages belonging to an inode are in these doubly linked lists:382382- * mapping->clean_pages, mapping->dirty_pages and mapping->locked_pages;383383- * using the page->list list_head. These fields are also used for384384- * freelist managemet (when page_count()==0).379379+ * Instead of keeping dirty/clean pages in per address-space lists, we instead380380+ * now tag pages as dirty/under writeback in the radix tree.385381 *386382 * There is also a per-mapping radix tree mapping index to the page387383 * in memory if present. The tree is rooted at mapping->root.
+34-5
include/linux/netfilter_ipv4/ip_conntrack.h
···133133134134#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>135135#include <linux/netfilter_ipv4/ip_conntrack_icmp.h>136136+#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>136137#include <linux/netfilter_ipv4/ip_conntrack_sctp.h>137138138139/* per conntrack: protocol private data */139140union ip_conntrack_proto {140141 /* insert conntrack proto private data here */142142+ struct ip_ct_gre gre;141143 struct ip_ct_sctp sctp;142144 struct ip_ct_tcp tcp;143145 struct ip_ct_icmp icmp;···150148};151149152150/* Add protocol helper include file here */151151+#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>153152#include <linux/netfilter_ipv4/ip_conntrack_amanda.h>154153#include <linux/netfilter_ipv4/ip_conntrack_ftp.h>155154#include <linux/netfilter_ipv4/ip_conntrack_irc.h>···158155/* per conntrack: application helper private data */159156union ip_conntrack_help {160157 /* insert conntrack helper private data (master) here */158158+ struct ip_ct_pptp_master ct_pptp_info;161159 struct ip_ct_ftp_master ct_ftp_info;162160 struct ip_ct_irc_master ct_irc_info;163161};164162165163#ifdef CONFIG_IP_NF_NAT_NEEDED166164#include <linux/netfilter_ipv4/ip_nat.h>165165+#include <linux/netfilter_ipv4/ip_nat_pptp.h>166166+167167+/* per conntrack: nat application helper private data */168168+union ip_conntrack_nat_help {169169+ /* insert nat helper private data here */170170+ struct ip_nat_pptp nat_pptp_info;171171+};167172#endif168173169174#include <linux/types.h>···234223#ifdef CONFIG_IP_NF_NAT_NEEDED235224 struct {236225 struct ip_nat_info info;226226+ union ip_conntrack_nat_help help;237227#if defined(CONFIG_IP_NF_TARGET_MASQUERADE) || \238228 defined(CONFIG_IP_NF_TARGET_MASQUERADE_MODULE)239229 int masq_index;···332320extern int invert_tuplepr(struct ip_conntrack_tuple *inverse,333321 const struct ip_conntrack_tuple *orig);334322323323+extern void __ip_ct_refresh_acct(struct ip_conntrack *ct,324324+ enum ip_conntrack_info ctinfo,325325+ const struct sk_buff *skb,326326+ unsigned long extra_jiffies,327327+ int do_acct);328328+329329+/* Refresh conntrack for this many jiffies and do accounting */330330+static inline void ip_ct_refresh_acct(struct ip_conntrack *ct, 331331+ enum ip_conntrack_info ctinfo,332332+ const struct sk_buff *skb,333333+ unsigned long extra_jiffies)334334+{335335+ __ip_ct_refresh_acct(ct, ctinfo, skb, extra_jiffies, 1);336336+}337337+335338/* Refresh conntrack for this many jiffies */336336-extern void ip_ct_refresh_acct(struct ip_conntrack *ct,337337- enum ip_conntrack_info ctinfo,338338- const struct sk_buff *skb,339339- unsigned long extra_jiffies);339339+static inline void ip_ct_refresh(struct ip_conntrack *ct,340340+ const struct sk_buff *skb,341341+ unsigned long extra_jiffies)342342+{343343+ __ip_ct_refresh_acct(ct, 0, skb, extra_jiffies, 0);344344+}340345341346/* These are for NAT. Icky. */342347/* Update TCP window tracking data when NAT mangles the packet */···401372__ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple);402373403374extern struct ip_conntrack_expect *404404-ip_conntrack_expect_find_get(const struct ip_conntrack_tuple *tuple);375375+ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple);405376406377extern struct ip_conntrack_tuple_hash *407378__ip_conntrack_find(const struct ip_conntrack_tuple *tuple,
···11+#ifndef _CONNTRACK_PROTO_GRE_H22+#define _CONNTRACK_PROTO_GRE_H33+#include <asm/byteorder.h>44+55+/* GRE PROTOCOL HEADER */66+77+/* GRE Version field */88+#define GRE_VERSION_1701 0x099+#define GRE_VERSION_PPTP 0x11010+1111+/* GRE Protocol field */1212+#define GRE_PROTOCOL_PPTP 0x880B1313+1414+/* GRE Flags */1515+#define GRE_FLAG_C 0x801616+#define GRE_FLAG_R 0x401717+#define GRE_FLAG_K 0x201818+#define GRE_FLAG_S 0x101919+#define GRE_FLAG_A 0x802020+2121+#define GRE_IS_C(f) ((f)&GRE_FLAG_C)2222+#define GRE_IS_R(f) ((f)&GRE_FLAG_R)2323+#define GRE_IS_K(f) ((f)&GRE_FLAG_K)2424+#define GRE_IS_S(f) ((f)&GRE_FLAG_S)2525+#define GRE_IS_A(f) ((f)&GRE_FLAG_A)2626+2727+/* GRE is a mess: Four different standards */2828+struct gre_hdr {2929+#if defined(__LITTLE_ENDIAN_BITFIELD)3030+ __u16 rec:3,3131+ srr:1,3232+ seq:1,3333+ key:1,3434+ routing:1,3535+ csum:1,3636+ version:3,3737+ reserved:4,3838+ ack:1;3939+#elif defined(__BIG_ENDIAN_BITFIELD)4040+ __u16 csum:1,4141+ routing:1,4242+ key:1,4343+ seq:1,4444+ srr:1,4545+ rec:3,4646+ ack:1,4747+ reserved:4,4848+ version:3;4949+#else5050+#error "Adjust your <asm/byteorder.h> defines"5151+#endif5252+ __u16 protocol;5353+};5454+5555+/* modified GRE header for PPTP */5656+struct gre_hdr_pptp {5757+ __u8 flags; /* bitfield */5858+ __u8 version; /* should be GRE_VERSION_PPTP */5959+ __u16 protocol; /* should be GRE_PROTOCOL_PPTP */6060+ __u16 payload_len; /* size of ppp payload, not inc. gre header */6161+ __u16 call_id; /* peer's call_id for this session */6262+ __u32 seq; /* sequence number. Present if S==1 */6363+ __u32 ack; /* seq number of highest packet recieved by */6464+ /* sender in this session */6565+};6666+6767+6868+/* this is part of ip_conntrack */6969+struct ip_ct_gre {7070+ unsigned int stream_timeout;7171+ unsigned int timeout;7272+};7373+7474+#ifdef __KERNEL__7575+struct ip_conntrack_expect;7676+struct ip_conntrack;7777+7878+/* structure for original <-> reply keymap */7979+struct ip_ct_gre_keymap {8080+ struct list_head list;8181+8282+ struct ip_conntrack_tuple tuple;8383+};8484+8585+/* add new tuple->key_reply pair to keymap */8686+int ip_ct_gre_keymap_add(struct ip_conntrack *ct,8787+ struct ip_conntrack_tuple *t,8888+ int reply);8989+9090+/* delete keymap entries */9191+void ip_ct_gre_keymap_destroy(struct ip_conntrack *ct);9292+9393+9494+/* get pointer to gre key, if present */9595+static inline u_int32_t *gre_key(struct gre_hdr *greh)9696+{9797+ if (!greh->key)9898+ return NULL;9999+ if (greh->csum || greh->routing)100100+ return (u_int32_t *) (greh+sizeof(*greh)+4);101101+ return (u_int32_t *) (greh+sizeof(*greh));102102+}103103+104104+/* get pointer ot gre csum, if present */105105+static inline u_int16_t *gre_csum(struct gre_hdr *greh)106106+{107107+ if (!greh->csum)108108+ return NULL;109109+ return (u_int16_t *) (greh+sizeof(*greh));110110+}111111+112112+#endif /* __KERNEL__ */113113+114114+#endif /* _CONNTRACK_PROTO_GRE_H */
+8-1
include/linux/netfilter_ipv4/ip_conntrack_tuple.h
···1717 u_int16_t all;18181919 struct {2020- u_int16_t port;2020+ __be16 port;2121 } tcp;2222 struct {2323 u_int16_t port;···2828 struct {2929 u_int16_t port;3030 } sctp;3131+ struct {3232+ __be16 key; /* key is 32bit, pptp only uses 16 */3333+ } gre;3134};32353336/* The manipulable part of the tuple. */···6461 struct {6562 u_int16_t port;6663 } sctp;6464+ struct {6565+ __be16 key; /* key is 32bit, 6666+ * pptp only uses 16 */6767+ } gre;6768 } u;68696970 /* The protocol. */
+11
include/linux/netfilter_ipv4/ip_nat_pptp.h
···11+/* PPTP constants and structs */22+#ifndef _NAT_PPTP_H33+#define _NAT_PPTP_H44+55+/* conntrack private data */66+struct ip_nat_pptp {77+ u_int16_t pns_call_id; /* NAT'ed PNS call id */88+ u_int16_t pac_call_id; /* NAT'ed PAC call id */99+};1010+1111+#endif /* _NAT_PPTP_H */
+3
include/linux/netfilter_ipv6/ip6_tables.h
···455455456456/* Check for an extension */457457extern int ip6t_ext_hdr(u8 nexthdr);458458+/* find specified header and get offset to it */459459+extern int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset,460460+ u8 target);458461459462#define IP6T_ALIGN(s) (((s) + (__alignof__(struct ip6t_entry)-1)) & ~(__alignof__(struct ip6t_entry)-1))460463
···508508509509asmlinkage long sys_ioprio_set(int which, int who, int ioprio);510510asmlinkage long sys_ioprio_get(int which, int who);511511+asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask,512512+ unsigned long maxnode);511513512514#endif
···439439 SHOST_CANCEL,440440 SHOST_DEL,441441 SHOST_RECOVERY,442442+ SHOST_CANCEL_RECOVERY,443443+ SHOST_DEL_RECOVERY,442444};443445444446struct Scsi_Host {···467465468466 struct list_head eh_cmd_q;469467 struct task_struct * ehandler; /* Error recovery thread. */470470- struct semaphore * eh_wait; /* The error recovery thread waits471471- on this. */472468 struct semaphore * eh_action; /* Wait for specific actions on the473469 host. */474470 unsigned int eh_active:1; /* Indicates the eh thread is awake and active if···619619 dev = dev->parent;620620 }621621 return container_of(dev, struct Scsi_Host, shost_gendev);622622+}623623+624624+static inline int scsi_host_in_recovery(struct Scsi_Host *shost)625625+{626626+ return shost->shost_state == SHOST_RECOVERY ||627627+ shost->shost_state == SHOST_CANCEL_RECOVERY ||628628+ shost->shost_state == SHOST_DEL_RECOVERY;622629}623630624631extern int scsi_queue_work(struct Scsi_Host *, struct work_struct *);
+2-2
include/scsi/scsi_transport_fc.h
···103103 incapable of reporting */104104#define FC_PORTSPEED_1GBIT 1105105#define FC_PORTSPEED_2GBIT 2106106-#define FC_PORTSPEED_10GBIT 4107107-#define FC_PORTSPEED_4GBIT 8106106+#define FC_PORTSPEED_4GBIT 4107107+#define FC_PORTSPEED_10GBIT 8108108#define FC_PORTSPEED_NOT_NEGOTIATED (1 << 15) /* Speed not established */109109110110/*
+1-1
kernel/power/Kconfig
···29293030config SOFTWARE_SUSPEND3131 bool "Software Suspend"3232- depends on PM && SWAP && (X86 || ((FVR || PPC32) && !SMP))3232+ depends on PM && SWAP && (X86 && (!SMP || SUSPEND_SMP)) || ((FVR || PPC32) && !SMP)3333 ---help---3434 Enable the possibility of suspending the machine.3535 It doesn't need APM.
+2-4
kernel/power/disk.c
···1717#include <linux/delay.h>1818#include <linux/fs.h>1919#include <linux/mount.h>2020+#include <linux/pm.h>20212122#include "power.h"222323242425extern suspend_disk_method_t pm_disk_mode;2525-extern struct pm_ops * pm_ops;26262727extern int swsusp_suspend(void);2828extern int swsusp_write(void);···49495050static void power_down(suspend_disk_method_t mode)5151{5252- unsigned long flags;5352 int error = 0;54535555- local_irq_save(flags);5654 switch(mode) {5755 case PM_DISK_PLATFORM:5858- device_shutdown();5656+ kernel_power_off_prepare();5957 error = pm_ops->enter(PM_SUSPEND_DISK);6058 break;6159 case PM_DISK_SHUTDOWN:
+1-1
kernel/power/power.h
···11#include <linux/suspend.h>22#include <linux/utsname.h>3344-/* With SUSPEND_CONSOLE defined, it suspend looks *really* cool, but44+/* With SUSPEND_CONSOLE defined suspend looks *really* cool, but55 we probably do not take enough locks for switching consoles, etc,66 so bad things might happen.77*/
+8-4
kernel/power/swsusp.c
···363363}364364365365/**366366- * write_swap_page - Write one page to a fresh swap location.366366+ * write_page - Write one page to a fresh swap location.367367 * @addr: Address we're writing.368368 * @loc: Place to store the entry we used.369369 *···863863 return 0;864864}865865866866+/* Free pages we allocated for suspend. Suspend pages are alocated867867+ * before atomic copy, so we need to free them after resume.868868+ */866869void swsusp_free(void)867870{868871 BUG_ON(PageNosave(virt_to_page(pagedir_save)));···921918922919 pagedir_nosave = NULL;923920 nr_copy_pages = calc_nr(nr_copy_pages);921921+ nr_copy_pages_check = nr_copy_pages;924922925923 pr_debug("suspend: (pages needed: %d + %d free: %d)\n",926924 nr_copy_pages, PAGES_FOR_IO, nr_free_pages());···944940 return error;945941 }946942947947- nr_copy_pages_check = nr_copy_pages;948943 return 0;949944}950945···12161213 free_pagedir(pblist);12171214 free_eaten_memory();12181215 pblist = NULL;12191219- }12201220- else12161216+ /* Is this even worth handling? It should never ever happen, and we12171217+ have just lost user's state, anyway... */12181218+ } else12211219 printk("swsusp: Relocated %d pages\n", rel);1222122012231221 return pblist;
+6-1
kernel/printk.c
···488488489489__setup("time", printk_time_setup);490490491491+__attribute__((weak)) unsigned long long printk_clock(void)492492+{493493+ return sched_clock();494494+}495495+491496/*492497 * This is printk. It can be called from any context. We want it to work.493498 * ···570565 loglev_char = default_message_loglevel571566 + '0';572567 }573573- t = sched_clock();568568+ t = printk_clock();574569 nanosec_rem = do_div(t, 1000000000);575570 tlen = sprintf(tbuf,576571 "<%c>[%5lu.%06lu] ",
+14-17
kernel/signal.c
···936936 * as soon as they're available, so putting the signal on the shared queue937937 * will be equivalent to sending it to one such thread.938938 */939939-#define wants_signal(sig, p, mask) \940940- (!sigismember(&(p)->blocked, sig) \941941- && !((p)->state & mask) \942942- && !((p)->flags & PF_EXITING) \943943- && (task_curr(p) || !signal_pending(p)))944944-939939+static inline int wants_signal(int sig, struct task_struct *p)940940+{941941+ if (sigismember(&p->blocked, sig))942942+ return 0;943943+ if (p->flags & PF_EXITING)944944+ return 0;945945+ if (sig == SIGKILL)946946+ return 1;947947+ if (p->state & (TASK_STOPPED | TASK_TRACED))948948+ return 0;949949+ return task_curr(p) || !signal_pending(p);950950+}945951946952static void947953__group_complete_signal(int sig, struct task_struct *p)948954{949949- unsigned int mask;950955 struct task_struct *t;951951-952952- /*953953- * Don't bother traced and stopped tasks (but954954- * SIGKILL will punch through that).955955- */956956- mask = TASK_STOPPED | TASK_TRACED;957957- if (sig == SIGKILL)958958- mask = 0;959956960957 /*961958 * Now find a thread we can wake up to take the signal off the queue.···960963 * If the main thread wants the signal, it gets first crack.961964 * Probably the least surprising to the average bear.962965 */963963- if (wants_signal(sig, p, mask))966966+ if (wants_signal(sig, p))964967 t = p;965968 else if (thread_group_empty(p))966969 /*···978981 t = p->signal->curr_target = p;979982 BUG_ON(t->tgid != p->tgid);980983981981- while (!wants_signal(sig, t, mask)) {984984+ while (!wants_signal(sig, t)) {982985 t = next_thread(t);983986 if (t == p->signal->curr_target)984987 /*
+46-6
kernel/sys.c
···361361 return retval;362362}363363364364+/**365365+ * emergency_restart - reboot the system366366+ *367367+ * Without shutting down any hardware or taking any locks368368+ * reboot the system. This is called when we know we are in369369+ * trouble so this is our best effort to reboot. This is370370+ * safe to call in interrupt context.371371+ */364372void emergency_restart(void)365373{366374 machine_emergency_restart();367375}368376EXPORT_SYMBOL_GPL(emergency_restart);369377370370-void kernel_restart(char *cmd)378378+/**379379+ * kernel_restart - reboot the system380380+ *381381+ * Shutdown everything and perform a clean reboot.382382+ * This is not safe to call in interrupt context.383383+ */384384+void kernel_restart_prepare(char *cmd)371385{372386 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, cmd);373387 system_state = SYSTEM_RESTART;374388 device_shutdown();389389+}390390+void kernel_restart(char *cmd)391391+{392392+ kernel_restart_prepare(cmd);375393 if (!cmd) {376394 printk(KERN_EMERG "Restarting system.\n");377395 } else {···400382}401383EXPORT_SYMBOL_GPL(kernel_restart);402384385385+/**386386+ * kernel_kexec - reboot the system387387+ *388388+ * Move into place and start executing a preloaded standalone389389+ * executable. If nothing was preloaded return an error.390390+ */403391void kernel_kexec(void)404392{405393#ifdef CONFIG_KEXEC···414390 if (!image) {415391 return;416392 }417417- notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);418418- system_state = SYSTEM_RESTART;419419- device_shutdown();393393+ kernel_restart_prepare(NULL);420394 printk(KERN_EMERG "Starting new kernel\n");421395 machine_shutdown();422396 machine_kexec(image);···422400}423401EXPORT_SYMBOL_GPL(kernel_kexec);424402425425-void kernel_halt(void)403403+/**404404+ * kernel_halt - halt the system405405+ *406406+ * Shutdown everything and perform a clean system halt.407407+ */408408+void kernel_halt_prepare(void)426409{427410 notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);428411 system_state = SYSTEM_HALT;429412 device_shutdown();413413+}414414+void kernel_halt(void)415415+{416416+ kernel_halt_prepare();430417 printk(KERN_EMERG "System halted.\n");431418 machine_halt();432419}433420EXPORT_SYMBOL_GPL(kernel_halt);434421435435-void kernel_power_off(void)422422+/**423423+ * kernel_power_off - power_off the system424424+ *425425+ * Shutdown everything and perform a clean system power_off.426426+ */427427+void kernel_power_off_prepare(void)436428{437429 notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);438430 system_state = SYSTEM_POWER_OFF;439431 device_shutdown();432432+}433433+void kernel_power_off(void)434434+{435435+ kernel_power_off_prepare();440436 printk(KERN_EMERG "Power down.\n");441437 machine_power_off();442438}
+1-1
mm/mmap.c
···16401640/*16411641 * Get rid of page table information in the indicated region.16421642 *16431643- * Called with the page table lock held.16431643+ * Called with the mm semaphore held.16441644 */16451645static void unmap_region(struct mm_struct *mm,16461646 struct vm_area_struct *vma, struct vm_area_struct *prev,
···120120 unsigned short vid;121121 struct net_device_stats *stats;122122 unsigned short vlan_TCI;123123- unsigned short proto;123123+ __be16 proto;124124125125 /* vlan_TCI = ntohs(get_unaligned(&vhdr->h_vlan_TCI)); */126126 vlan_TCI = ntohs(vhdr->h_vlan_TCI);
+2-1
net/bridge/br_forward.c
···31313232int br_dev_queue_push_xmit(struct sk_buff *skb)3333{3434- if (skb->len > skb->dev->mtu) 3434+ /* drop mtu oversized packets except tso */3535+ if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->tso_size)3536 kfree_skb(skb);3637 else {3738#ifdef CONFIG_BRIDGE_NETFILTER
+20-29
net/ipv4/fib_trie.c
···4343 * 2 of the License, or (at your option) any later version.4444 */45454646-#define VERSION "0.403"4646+#define VERSION "0.404"47474848#include <linux/config.h>4949#include <asm/uaccess.h>···224224 Consider a node 'n' and its parent 'tp'.225225226226 If n is a leaf, every bit in its key is significant. Its presence is 227227- necessitaded by path compression, since during a tree traversal (when 227227+ necessitated by path compression, since during a tree traversal (when 228228 searching for a leaf - unless we are doing an insertion) we will completely 229229 ignore all skipped bits we encounter. Thus we need to verify, at the end of 230230 a potentially successful search, that we have indeed been walking the ···836836#endif837837}838838839839-/* readside most use rcu_read_lock currently dump routines839839+/* readside must use rcu_read_lock currently dump routines840840 via get_fa_head and dump */841841842842-static struct leaf_info *find_leaf_info(struct hlist_head *head, int plen)842842+static struct leaf_info *find_leaf_info(struct leaf *l, int plen)843843{844844+ struct hlist_head *head = &l->list;844845 struct hlist_node *node;845846 struct leaf_info *li;846847···854853855854static inline struct list_head * get_fa_head(struct leaf *l, int plen)856855{857857- struct leaf_info *li = find_leaf_info(&l->list, plen);856856+ struct leaf_info *li = find_leaf_info(l, plen);858857859858 if (!li)860859 return NULL;···10861085 }1087108610881087 if (tp && tp->pos + tp->bits > 32)10891089- printk("ERROR tp=%p pos=%d, bits=%d, key=%0x plen=%d\n",10881088+ printk(KERN_WARNING "fib_trie tp=%p pos=%d, bits=%d, key=%0x plen=%d\n",10901089 tp, tp->pos, tp->bits, key, plen);1091109010921091 /* Rebalance the trie */···12491248}125012491251125012521252-/* should be clalled with rcu_read_lock */12511251+/* should be called with rcu_read_lock */12531252static inline int check_leaf(struct trie *t, struct leaf *l,12541253 t_key key, int *plen, const struct flowi *flp,12551254 struct fib_result *res)···15911590 rtmsg_fib(RTM_DELROUTE, htonl(key), fa, plen, tb->tb_id, nlhdr, req);1592159115931592 l = fib_find_node(t, key);15941594- li = find_leaf_info(&l->list, plen);15931593+ li = find_leaf_info(l, plen);1595159415961595 list_del_rcu(&fa->fa_list);15971596···1715171417161715 t->revision++;1717171617181718- rcu_read_lock();17191717 for (h = 0; (l = nextleaf(t, l)) != NULL; h++) {17201718 found += trie_flush_leaf(t, l);17211719···17221722 trie_leaf_remove(t, ll->key);17231723 ll = l;17241724 }17251725- rcu_read_unlock(); 1726172517271726 if (ll && hlist_empty(&ll->list))17281727 trie_leaf_remove(t, ll->key);···18321833 i++;18331834 continue;18341835 }18351835- if (fa->fa_info->fib_nh == NULL) {18361836- printk("Trie error _fib_nh=NULL in fa[%d] k=%08x plen=%d\n", i, key, plen);18371837- i++;18381838- continue;18391839- }18401840- if (fa->fa_info == NULL) {18411841- printk("Trie error fa_info=NULL in fa[%d] k=%08x plen=%d\n", i, key, plen);18421842- i++;18431843- continue;18441844- }18361836+ BUG_ON(!fa->fa_info);1845183718461838 if (fib_dump_info(skb, NETLINK_CB(cb->skb).pid,18471839 cb->nlh->nlmsg_seq,···19551965 trie_main = t;1956196619571967 if (id == RT_TABLE_LOCAL)19581958- printk("IPv4 FIB: Using LC-trie version %s\n", VERSION);19681968+ printk(KERN_INFO "IPv4 FIB: Using LC-trie version %s\n", VERSION);1959196919601970 return tb;19611971}···20192029 iter->tnode = (struct tnode *) n;20202030 iter->trie = t;20212031 iter->index = 0;20222022- iter->depth = 0;20322032+ iter->depth = 1;20232033 return n;20242034 }20252035 return NULL;···22642274 seq_puts(seq, "<local>:\n");22652275 else22662276 seq_puts(seq, "<main>:\n");22672267- } else {22682268- seq_indent(seq, iter->depth-1);22692269- seq_printf(seq, " +-- %d.%d.%d.%d/%d\n",22702270- NIPQUAD(prf), tn->pos);22712271- }22772277+ } 22782278+ seq_indent(seq, iter->depth-1);22792279+ seq_printf(seq, " +-- %d.%d.%d.%d/%d %d %d %d\n",22802280+ NIPQUAD(prf), tn->pos, tn->bits, tn->full_children, 22812281+ tn->empty_children);22822282+22722283 } else {22732284 struct leaf *l = (struct leaf *) n;22742285 int i;···22782287 seq_indent(seq, iter->depth);22792288 seq_printf(seq, " |-- %d.%d.%d.%d\n", NIPQUAD(val));22802289 for (i = 32; i >= 0; i--) {22812281- struct leaf_info *li = find_leaf_info(&l->list, i);22902290+ struct leaf_info *li = find_leaf_info(l, i);22822291 if (li) {22832292 struct fib_alias *fa;22842293 list_for_each_entry_rcu(fa, &li->falh, fa_list) {···23742383 return 0;2375238423762385 for (i=32; i>=0; i--) {23772377- struct leaf_info *li = find_leaf_info(&l->list, i);23862386+ struct leaf_info *li = find_leaf_info(l, i);23782387 struct fib_alias *fa;23792388 u32 mask, prefix;23802389
+22
net/ipv4/netfilter/Kconfig
···137137138138 To compile it as a module, choose M here. If unsure, say Y.139139140140+config IP_NF_PPTP141141+ tristate 'PPTP protocol support'142142+ help143143+ This module adds support for PPTP (Point to Point Tunnelling144144+ Protocol, RFC2637) conncection tracking and NAT. 145145+146146+ If you are running PPTP sessions over a stateful firewall or NAT147147+ box, you may want to enable this feature. 148148+149149+ Please note that not all PPTP modes of operation are supported yet.150150+ For more info, read top of the file151151+ net/ipv4/netfilter/ip_conntrack_pptp.c152152+153153+ If you want to compile it as a module, say M here and read154154+ Documentation/modules.txt. If unsure, say `N'.155155+140156config IP_NF_QUEUE141157 tristate "IP Userspace queueing via NETLINK (OBSOLETE)"142158 help···636620 depends on IP_NF_IPTABLES!=n && IP_NF_CONNTRACK!=n && IP_NF_NAT!=n637621 default IP_NF_NAT if IP_NF_AMANDA=y638622 default m if IP_NF_AMANDA=m623623+624624+config IP_NF_NAT_PPTP625625+ tristate626626+ depends on IP_NF_NAT!=n && IP_NF_PPTP!=n627627+ default IP_NF_NAT if IP_NF_PPTP=y628628+ default m if IP_NF_PPTP=m639629640630# mangle + specific targets641631config IP_NF_MANGLE
···65656666 /* increase the UDP timeout of the master connection as replies from6767 * Amanda clients to the server can be quite delayed */6868- ip_ct_refresh_acct(ct, ctinfo, NULL, master_timeout * HZ);6868+ ip_ct_refresh(ct, *pskb, master_timeout * HZ);69697070 /* No data? */7171 dataoff = (*pskb)->nh.iph->ihl*4 + sizeof(struct udphdr);
+26-25
net/ipv4/netfilter/ip_conntrack_core.c
···233233234234/* Just find a expectation corresponding to a tuple. */235235struct ip_conntrack_expect *236236-ip_conntrack_expect_find_get(const struct ip_conntrack_tuple *tuple)236236+ip_conntrack_expect_find(const struct ip_conntrack_tuple *tuple)237237{238238 struct ip_conntrack_expect *i;239239···11121112 synchronize_net();11131113}1114111411151115-static inline void ct_add_counters(struct ip_conntrack *ct,11161116- enum ip_conntrack_info ctinfo,11171117- const struct sk_buff *skb)11181118-{11191119-#ifdef CONFIG_IP_NF_CT_ACCT11201120- if (skb) {11211121- ct->counters[CTINFO2DIR(ctinfo)].packets++;11221122- ct->counters[CTINFO2DIR(ctinfo)].bytes += 11231123- ntohs(skb->nh.iph->tot_len);11241124- }11251125-#endif11261126-}11271127-11281128-/* Refresh conntrack for this many jiffies and do accounting (if skb != NULL) */11291129-void ip_ct_refresh_acct(struct ip_conntrack *ct, 11151115+/* Refresh conntrack for this many jiffies and do accounting if do_acct is 1 */11161116+void __ip_ct_refresh_acct(struct ip_conntrack *ct, 11301117 enum ip_conntrack_info ctinfo,11311118 const struct sk_buff *skb,11321132- unsigned long extra_jiffies)11191119+ unsigned long extra_jiffies,11201120+ int do_acct)11331121{11221122+ int do_event = 0;11231123+11341124 IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct);11251125+ IP_NF_ASSERT(skb);11261126+11271127+ write_lock_bh(&ip_conntrack_lock);1135112811361129 /* If not in hash table, timer will not be active yet */11371130 if (!is_confirmed(ct)) {11381131 ct->timeout.expires = extra_jiffies;11391139- ct_add_counters(ct, ctinfo, skb);11321132+ do_event = 1;11401133 } else {11411141- write_lock_bh(&ip_conntrack_lock);11421134 /* Need del_timer for race avoidance (may already be dying). */11431135 if (del_timer(&ct->timeout)) {11441136 ct->timeout.expires = jiffies + extra_jiffies;11451137 add_timer(&ct->timeout);11461146- /* FIXME: We loose some REFRESH events if this function11471147- * is called without an skb. I'll fix this later -HW */11481148- if (skb)11491149- ip_conntrack_event_cache(IPCT_REFRESH, skb);11381138+ do_event = 1;11501139 }11511151- ct_add_counters(ct, ctinfo, skb);11521152- write_unlock_bh(&ip_conntrack_lock);11531140 }11411141+11421142+#ifdef CONFIG_IP_NF_CT_ACCT11431143+ if (do_acct) {11441144+ ct->counters[CTINFO2DIR(ctinfo)].packets++;11451145+ ct->counters[CTINFO2DIR(ctinfo)].bytes += 11461146+ ntohs(skb->nh.iph->tot_len);11471147+ }11481148+#endif11491149+11501150+ write_unlock_bh(&ip_conntrack_lock);11511151+11521152+ /* must be unlocked when calling event cache */11531153+ if (do_event)11541154+ ip_conntrack_event_cache(IPCT_REFRESH, skb);11541155}1155115611561157#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
+806
net/ipv4/netfilter/ip_conntrack_helper_pptp.c
···11+/*22+ * ip_conntrack_pptp.c - Version 3.033+ *44+ * Connection tracking support for PPTP (Point to Point Tunneling Protocol).55+ * PPTP is a a protocol for creating virtual private networks.66+ * It is a specification defined by Microsoft and some vendors77+ * working with Microsoft. PPTP is built on top of a modified88+ * version of the Internet Generic Routing Encapsulation Protocol.99+ * GRE is defined in RFC 1701 and RFC 1702. Documentation of1010+ * PPTP can be found in RFC 26371111+ *1212+ * (C) 2000-2005 by Harald Welte <laforge@gnumonks.org>1313+ *1414+ * Development of this code funded by Astaro AG (http://www.astaro.com/)1515+ *1616+ * Limitations:1717+ * - We blindly assume that control connections are always1818+ * established in PNS->PAC direction. This is a violation1919+ * of RFFC26732020+ * - We can only support one single call within each session2121+ *2222+ * TODO:2323+ * - testing of incoming PPTP calls 2424+ *2525+ * Changes: 2626+ * 2002-02-05 - Version 1.32727+ * - Call ip_conntrack_unexpect_related() from 2828+ * pptp_destroy_siblings() to destroy expectations in case2929+ * CALL_DISCONNECT_NOTIFY or tcp fin packet was seen3030+ * (Philip Craig <philipc@snapgear.com>)3131+ * - Add Version information at module loadtime3232+ * 2002-02-10 - Version 1.63333+ * - move to C99 style initializers3434+ * - remove second expectation if first arrives3535+ * 2004-10-22 - Version 2.03636+ * - merge Mandrake's 2.6.x port with recent 2.6.x API changes3737+ * - fix lots of linear skb assumptions from Mandrake's port3838+ * 2005-06-10 - Version 2.13939+ * - use ip_conntrack_expect_free() instead of kfree() on the4040+ * expect's (which are from the slab for quite some time)4141+ * 2005-06-10 - Version 3.04242+ * - port helper to post-2.6.11 API changes,4343+ * funded by Oxcoda NetBox Blue (http://www.netboxblue.com/)4444+ * 2005-07-30 - Version 3.14545+ * - port helper to 2.6.13 API changes4646+ *4747+ */4848+4949+#include <linux/config.h>5050+#include <linux/module.h>5151+#include <linux/netfilter.h>5252+#include <linux/ip.h>5353+#include <net/checksum.h>5454+#include <net/tcp.h>5555+5656+#include <linux/netfilter_ipv4/ip_conntrack.h>5757+#include <linux/netfilter_ipv4/ip_conntrack_core.h>5858+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>5959+#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>6060+#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>6161+6262+#define IP_CT_PPTP_VERSION "3.1"6363+6464+MODULE_LICENSE("GPL");6565+MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");6666+MODULE_DESCRIPTION("Netfilter connection tracking helper module for PPTP");6767+6868+static DEFINE_SPINLOCK(ip_pptp_lock);6969+7070+int7171+(*ip_nat_pptp_hook_outbound)(struct sk_buff **pskb,7272+ struct ip_conntrack *ct,7373+ enum ip_conntrack_info ctinfo,7474+ struct PptpControlHeader *ctlh,7575+ union pptp_ctrl_union *pptpReq);7676+7777+int7878+(*ip_nat_pptp_hook_inbound)(struct sk_buff **pskb,7979+ struct ip_conntrack *ct,8080+ enum ip_conntrack_info ctinfo,8181+ struct PptpControlHeader *ctlh,8282+ union pptp_ctrl_union *pptpReq);8383+8484+int8585+(*ip_nat_pptp_hook_exp_gre)(struct ip_conntrack_expect *expect_orig,8686+ struct ip_conntrack_expect *expect_reply);8787+8888+void8989+(*ip_nat_pptp_hook_expectfn)(struct ip_conntrack *ct,9090+ struct ip_conntrack_expect *exp);9191+9292+#if 09393+/* PptpControlMessageType names */9494+const char *pptp_msg_name[] = {9595+ "UNKNOWN_MESSAGE",9696+ "START_SESSION_REQUEST",9797+ "START_SESSION_REPLY",9898+ "STOP_SESSION_REQUEST",9999+ "STOP_SESSION_REPLY",100100+ "ECHO_REQUEST",101101+ "ECHO_REPLY",102102+ "OUT_CALL_REQUEST",103103+ "OUT_CALL_REPLY",104104+ "IN_CALL_REQUEST",105105+ "IN_CALL_REPLY",106106+ "IN_CALL_CONNECT",107107+ "CALL_CLEAR_REQUEST",108108+ "CALL_DISCONNECT_NOTIFY",109109+ "WAN_ERROR_NOTIFY",110110+ "SET_LINK_INFO"111111+};112112+EXPORT_SYMBOL(pptp_msg_name);113113+#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, __FUNCTION__, ## args)114114+#else115115+#define DEBUGP(format, args...)116116+#endif117117+118118+#define SECS *HZ119119+#define MINS * 60 SECS120120+#define HOURS * 60 MINS121121+122122+#define PPTP_GRE_TIMEOUT (10 MINS)123123+#define PPTP_GRE_STREAM_TIMEOUT (5 HOURS)124124+125125+static void pptp_expectfn(struct ip_conntrack *ct,126126+ struct ip_conntrack_expect *exp)127127+{128128+ DEBUGP("increasing timeouts\n");129129+130130+ /* increase timeout of GRE data channel conntrack entry */131131+ ct->proto.gre.timeout = PPTP_GRE_TIMEOUT;132132+ ct->proto.gre.stream_timeout = PPTP_GRE_STREAM_TIMEOUT;133133+134134+ /* Can you see how rusty this code is, compared with the pre-2.6.11135135+ * one? That's what happened to my shiny newnat of 2002 ;( -HW */136136+137137+ if (!ip_nat_pptp_hook_expectfn) {138138+ struct ip_conntrack_tuple inv_t;139139+ struct ip_conntrack_expect *exp_other;140140+141141+ /* obviously this tuple inversion only works until you do NAT */142142+ invert_tuplepr(&inv_t, &exp->tuple);143143+ DEBUGP("trying to unexpect other dir: ");144144+ DUMP_TUPLE(&inv_t);145145+146146+ exp_other = ip_conntrack_expect_find(&inv_t);147147+ if (exp_other) {148148+ /* delete other expectation. */149149+ DEBUGP("found\n");150150+ ip_conntrack_unexpect_related(exp_other);151151+ ip_conntrack_expect_put(exp_other);152152+ } else {153153+ DEBUGP("not found\n");154154+ }155155+ } else {156156+ /* we need more than simple inversion */157157+ ip_nat_pptp_hook_expectfn(ct, exp);158158+ }159159+}160160+161161+static int destroy_sibling_or_exp(const struct ip_conntrack_tuple *t)162162+{163163+ struct ip_conntrack_tuple_hash *h;164164+ struct ip_conntrack_expect *exp;165165+166166+ DEBUGP("trying to timeout ct or exp for tuple ");167167+ DUMP_TUPLE(t);168168+169169+ h = ip_conntrack_find_get(t, NULL);170170+ if (h) {171171+ struct ip_conntrack *sibling = tuplehash_to_ctrack(h);172172+ DEBUGP("setting timeout of conntrack %p to 0\n", sibling);173173+ sibling->proto.gre.timeout = 0;174174+ sibling->proto.gre.stream_timeout = 0;175175+ if (del_timer(&sibling->timeout))176176+ sibling->timeout.function((unsigned long)sibling);177177+ ip_conntrack_put(sibling);178178+ return 1;179179+ } else {180180+ exp = ip_conntrack_expect_find(t);181181+ if (exp) {182182+ DEBUGP("unexpect_related of expect %p\n", exp);183183+ ip_conntrack_unexpect_related(exp);184184+ ip_conntrack_expect_put(exp);185185+ return 1;186186+ }187187+ }188188+189189+ return 0;190190+}191191+192192+193193+/* timeout GRE data connections */194194+static void pptp_destroy_siblings(struct ip_conntrack *ct)195195+{196196+ struct ip_conntrack_tuple t;197197+198198+ /* Since ct->sibling_list has literally rusted away in 2.6.11, 199199+ * we now need another way to find out about our sibling200200+ * contrack and expects... -HW */201201+202202+ /* try original (pns->pac) tuple */203203+ memcpy(&t, &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple, sizeof(t));204204+ t.dst.protonum = IPPROTO_GRE;205205+ t.src.u.gre.key = htons(ct->help.ct_pptp_info.pns_call_id);206206+ t.dst.u.gre.key = htons(ct->help.ct_pptp_info.pac_call_id);207207+208208+ if (!destroy_sibling_or_exp(&t))209209+ DEBUGP("failed to timeout original pns->pac ct/exp\n");210210+211211+ /* try reply (pac->pns) tuple */212212+ memcpy(&t, &ct->tuplehash[IP_CT_DIR_REPLY].tuple, sizeof(t));213213+ t.dst.protonum = IPPROTO_GRE;214214+ t.src.u.gre.key = htons(ct->help.ct_pptp_info.pac_call_id);215215+ t.dst.u.gre.key = htons(ct->help.ct_pptp_info.pns_call_id);216216+217217+ if (!destroy_sibling_or_exp(&t))218218+ DEBUGP("failed to timeout reply pac->pns ct/exp\n");219219+}220220+221221+/* expect GRE connections (PNS->PAC and PAC->PNS direction) */222222+static inline int223223+exp_gre(struct ip_conntrack *master,224224+ u_int32_t seq,225225+ __be16 callid,226226+ __be16 peer_callid)227227+{228228+ struct ip_conntrack_tuple inv_tuple;229229+ struct ip_conntrack_tuple exp_tuples[] = {230230+ /* tuple in original direction, PNS->PAC */231231+ { .src = { .ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip,232232+ .u = { .gre = { .key = peer_callid } }233233+ },234234+ .dst = { .ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip,235235+ .u = { .gre = { .key = callid } },236236+ .protonum = IPPROTO_GRE237237+ },238238+ },239239+ /* tuple in reply direction, PAC->PNS */240240+ { .src = { .ip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip,241241+ .u = { .gre = { .key = callid } }242242+ },243243+ .dst = { .ip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip,244244+ .u = { .gre = { .key = peer_callid } },245245+ .protonum = IPPROTO_GRE246246+ },247247+ }248248+ };249249+ struct ip_conntrack_expect *exp_orig, *exp_reply;250250+ int ret = 1;251251+252252+ exp_orig = ip_conntrack_expect_alloc(master);253253+ if (exp_orig == NULL)254254+ goto out;255255+256256+ exp_reply = ip_conntrack_expect_alloc(master);257257+ if (exp_reply == NULL)258258+ goto out_put_orig;259259+260260+ memcpy(&exp_orig->tuple, &exp_tuples[0], sizeof(exp_orig->tuple));261261+262262+ exp_orig->mask.src.ip = 0xffffffff;263263+ exp_orig->mask.src.u.all = 0;264264+ exp_orig->mask.dst.u.all = 0;265265+ exp_orig->mask.dst.u.gre.key = htons(0xffff);266266+ exp_orig->mask.dst.ip = 0xffffffff;267267+ exp_orig->mask.dst.protonum = 0xff;268268+269269+ exp_orig->master = master;270270+ exp_orig->expectfn = pptp_expectfn;271271+ exp_orig->flags = 0;272272+273273+ exp_orig->dir = IP_CT_DIR_ORIGINAL;274274+275275+ /* both expectations are identical apart from tuple */276276+ memcpy(exp_reply, exp_orig, sizeof(*exp_reply));277277+ memcpy(&exp_reply->tuple, &exp_tuples[1], sizeof(exp_reply->tuple));278278+279279+ exp_reply->dir = !exp_orig->dir;280280+281281+ if (ip_nat_pptp_hook_exp_gre)282282+ ret = ip_nat_pptp_hook_exp_gre(exp_orig, exp_reply);283283+ else {284284+285285+ DEBUGP("calling expect_related PNS->PAC");286286+ DUMP_TUPLE(&exp_orig->tuple);287287+288288+ if (ip_conntrack_expect_related(exp_orig) != 0) {289289+ DEBUGP("cannot expect_related()\n");290290+ goto out_put_both;291291+ }292292+293293+ DEBUGP("calling expect_related PAC->PNS");294294+ DUMP_TUPLE(&exp_reply->tuple);295295+296296+ if (ip_conntrack_expect_related(exp_reply) != 0) {297297+ DEBUGP("cannot expect_related()\n");298298+ goto out_unexpect_orig;299299+ }300300+301301+ /* Add GRE keymap entries */302302+ if (ip_ct_gre_keymap_add(master, &exp_reply->tuple, 0) != 0) {303303+ DEBUGP("cannot keymap_add() exp\n");304304+ goto out_unexpect_both;305305+ }306306+307307+ invert_tuplepr(&inv_tuple, &exp_reply->tuple);308308+ if (ip_ct_gre_keymap_add(master, &inv_tuple, 1) != 0) {309309+ ip_ct_gre_keymap_destroy(master);310310+ DEBUGP("cannot keymap_add() exp_inv\n");311311+ goto out_unexpect_both;312312+ }313313+ ret = 0;314314+ }315315+316316+out_put_both:317317+ ip_conntrack_expect_put(exp_reply);318318+out_put_orig:319319+ ip_conntrack_expect_put(exp_orig);320320+out:321321+ return ret;322322+323323+out_unexpect_both:324324+ ip_conntrack_unexpect_related(exp_reply);325325+out_unexpect_orig:326326+ ip_conntrack_unexpect_related(exp_orig);327327+ goto out_put_both;328328+}329329+330330+static inline int 331331+pptp_inbound_pkt(struct sk_buff **pskb,332332+ struct tcphdr *tcph,333333+ unsigned int nexthdr_off,334334+ unsigned int datalen,335335+ struct ip_conntrack *ct,336336+ enum ip_conntrack_info ctinfo)337337+{338338+ struct PptpControlHeader _ctlh, *ctlh;339339+ unsigned int reqlen;340340+ union pptp_ctrl_union _pptpReq, *pptpReq;341341+ struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;342342+ u_int16_t msg;343343+ __be16 *cid, *pcid;344344+ u_int32_t seq; 345345+346346+ ctlh = skb_header_pointer(*pskb, nexthdr_off, sizeof(_ctlh), &_ctlh);347347+ if (!ctlh) {348348+ DEBUGP("error during skb_header_pointer\n");349349+ return NF_ACCEPT;350350+ }351351+ nexthdr_off += sizeof(_ctlh);352352+ datalen -= sizeof(_ctlh);353353+354354+ reqlen = datalen;355355+ if (reqlen > sizeof(*pptpReq))356356+ reqlen = sizeof(*pptpReq);357357+ pptpReq = skb_header_pointer(*pskb, nexthdr_off, reqlen, &_pptpReq);358358+ if (!pptpReq) {359359+ DEBUGP("error during skb_header_pointer\n");360360+ return NF_ACCEPT;361361+ }362362+363363+ msg = ntohs(ctlh->messageType);364364+ DEBUGP("inbound control message %s\n", pptp_msg_name[msg]);365365+366366+ switch (msg) {367367+ case PPTP_START_SESSION_REPLY:368368+ if (reqlen < sizeof(_pptpReq.srep)) {369369+ DEBUGP("%s: short packet\n", pptp_msg_name[msg]);370370+ break;371371+ }372372+373373+ /* server confirms new control session */374374+ if (info->sstate < PPTP_SESSION_REQUESTED) {375375+ DEBUGP("%s without START_SESS_REQUEST\n",376376+ pptp_msg_name[msg]);377377+ break;378378+ }379379+ if (pptpReq->srep.resultCode == PPTP_START_OK)380380+ info->sstate = PPTP_SESSION_CONFIRMED;381381+ else 382382+ info->sstate = PPTP_SESSION_ERROR;383383+ break;384384+385385+ case PPTP_STOP_SESSION_REPLY:386386+ if (reqlen < sizeof(_pptpReq.strep)) {387387+ DEBUGP("%s: short packet\n", pptp_msg_name[msg]);388388+ break;389389+ }390390+391391+ /* server confirms end of control session */392392+ if (info->sstate > PPTP_SESSION_STOPREQ) {393393+ DEBUGP("%s without STOP_SESS_REQUEST\n",394394+ pptp_msg_name[msg]);395395+ break;396396+ }397397+ if (pptpReq->strep.resultCode == PPTP_STOP_OK)398398+ info->sstate = PPTP_SESSION_NONE;399399+ else400400+ info->sstate = PPTP_SESSION_ERROR;401401+ break;402402+403403+ case PPTP_OUT_CALL_REPLY:404404+ if (reqlen < sizeof(_pptpReq.ocack)) {405405+ DEBUGP("%s: short packet\n", pptp_msg_name[msg]);406406+ break;407407+ }408408+409409+ /* server accepted call, we now expect GRE frames */410410+ if (info->sstate != PPTP_SESSION_CONFIRMED) {411411+ DEBUGP("%s but no session\n", pptp_msg_name[msg]);412412+ break;413413+ }414414+ if (info->cstate != PPTP_CALL_OUT_REQ &&415415+ info->cstate != PPTP_CALL_OUT_CONF) {416416+ DEBUGP("%s without OUTCALL_REQ\n", pptp_msg_name[msg]);417417+ break;418418+ }419419+ if (pptpReq->ocack.resultCode != PPTP_OUTCALL_CONNECT) {420420+ info->cstate = PPTP_CALL_NONE;421421+ break;422422+ }423423+424424+ cid = &pptpReq->ocack.callID;425425+ pcid = &pptpReq->ocack.peersCallID;426426+427427+ info->pac_call_id = ntohs(*cid);428428+429429+ if (htons(info->pns_call_id) != *pcid) {430430+ DEBUGP("%s for unknown callid %u\n",431431+ pptp_msg_name[msg], ntohs(*pcid));432432+ break;433433+ }434434+435435+ DEBUGP("%s, CID=%X, PCID=%X\n", pptp_msg_name[msg], 436436+ ntohs(*cid), ntohs(*pcid));437437+438438+ info->cstate = PPTP_CALL_OUT_CONF;439439+440440+ seq = ntohl(tcph->seq) + sizeof(struct pptp_pkt_hdr)441441+ + sizeof(struct PptpControlHeader)442442+ + ((void *)pcid - (void *)pptpReq);443443+444444+ if (exp_gre(ct, seq, *cid, *pcid) != 0)445445+ printk("ip_conntrack_pptp: error during exp_gre\n");446446+ break;447447+448448+ case PPTP_IN_CALL_REQUEST:449449+ if (reqlen < sizeof(_pptpReq.icack)) {450450+ DEBUGP("%s: short packet\n", pptp_msg_name[msg]);451451+ break;452452+ }453453+454454+ /* server tells us about incoming call request */455455+ if (info->sstate != PPTP_SESSION_CONFIRMED) {456456+ DEBUGP("%s but no session\n", pptp_msg_name[msg]);457457+ break;458458+ }459459+ pcid = &pptpReq->icack.peersCallID;460460+ DEBUGP("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(*pcid));461461+ info->cstate = PPTP_CALL_IN_REQ;462462+ info->pac_call_id = ntohs(*pcid);463463+ break;464464+465465+ case PPTP_IN_CALL_CONNECT:466466+ if (reqlen < sizeof(_pptpReq.iccon)) {467467+ DEBUGP("%s: short packet\n", pptp_msg_name[msg]);468468+ break;469469+ }470470+471471+ /* server tells us about incoming call established */472472+ if (info->sstate != PPTP_SESSION_CONFIRMED) {473473+ DEBUGP("%s but no session\n", pptp_msg_name[msg]);474474+ break;475475+ }476476+ if (info->sstate != PPTP_CALL_IN_REP477477+ && info->sstate != PPTP_CALL_IN_CONF) {478478+ DEBUGP("%s but never sent IN_CALL_REPLY\n",479479+ pptp_msg_name[msg]);480480+ break;481481+ }482482+483483+ pcid = &pptpReq->iccon.peersCallID;484484+ cid = &info->pac_call_id;485485+486486+ if (info->pns_call_id != ntohs(*pcid)) {487487+ DEBUGP("%s for unknown CallID %u\n", 488488+ pptp_msg_name[msg], ntohs(*pcid));489489+ break;490490+ }491491+492492+ DEBUGP("%s, PCID=%X\n", pptp_msg_name[msg], ntohs(*pcid));493493+ info->cstate = PPTP_CALL_IN_CONF;494494+495495+ /* we expect a GRE connection from PAC to PNS */496496+ seq = ntohl(tcph->seq) + sizeof(struct pptp_pkt_hdr)497497+ + sizeof(struct PptpControlHeader)498498+ + ((void *)pcid - (void *)pptpReq);499499+500500+ if (exp_gre(ct, seq, *cid, *pcid) != 0)501501+ printk("ip_conntrack_pptp: error during exp_gre\n");502502+503503+ break;504504+505505+ case PPTP_CALL_DISCONNECT_NOTIFY:506506+ if (reqlen < sizeof(_pptpReq.disc)) {507507+ DEBUGP("%s: short packet\n", pptp_msg_name[msg]);508508+ break;509509+ }510510+511511+ /* server confirms disconnect */512512+ cid = &pptpReq->disc.callID;513513+ DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(*cid));514514+ info->cstate = PPTP_CALL_NONE;515515+516516+ /* untrack this call id, unexpect GRE packets */517517+ pptp_destroy_siblings(ct);518518+ break;519519+520520+ case PPTP_WAN_ERROR_NOTIFY:521521+ break;522522+523523+ case PPTP_ECHO_REQUEST:524524+ case PPTP_ECHO_REPLY:525525+ /* I don't have to explain these ;) */526526+ break;527527+ default:528528+ DEBUGP("invalid %s (TY=%d)\n", (msg <= PPTP_MSG_MAX)529529+ ? pptp_msg_name[msg]:pptp_msg_name[0], msg);530530+ break;531531+ }532532+533533+534534+ if (ip_nat_pptp_hook_inbound)535535+ return ip_nat_pptp_hook_inbound(pskb, ct, ctinfo, ctlh,536536+ pptpReq);537537+538538+ return NF_ACCEPT;539539+540540+}541541+542542+static inline int543543+pptp_outbound_pkt(struct sk_buff **pskb,544544+ struct tcphdr *tcph,545545+ unsigned int nexthdr_off,546546+ unsigned int datalen,547547+ struct ip_conntrack *ct,548548+ enum ip_conntrack_info ctinfo)549549+{550550+ struct PptpControlHeader _ctlh, *ctlh;551551+ unsigned int reqlen;552552+ union pptp_ctrl_union _pptpReq, *pptpReq;553553+ struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;554554+ u_int16_t msg;555555+ __be16 *cid, *pcid;556556+557557+ ctlh = skb_header_pointer(*pskb, nexthdr_off, sizeof(_ctlh), &_ctlh);558558+ if (!ctlh)559559+ return NF_ACCEPT;560560+ nexthdr_off += sizeof(_ctlh);561561+ datalen -= sizeof(_ctlh);562562+563563+ reqlen = datalen;564564+ if (reqlen > sizeof(*pptpReq))565565+ reqlen = sizeof(*pptpReq);566566+ pptpReq = skb_header_pointer(*pskb, nexthdr_off, reqlen, &_pptpReq);567567+ if (!pptpReq)568568+ return NF_ACCEPT;569569+570570+ msg = ntohs(ctlh->messageType);571571+ DEBUGP("outbound control message %s\n", pptp_msg_name[msg]);572572+573573+ switch (msg) {574574+ case PPTP_START_SESSION_REQUEST:575575+ /* client requests for new control session */576576+ if (info->sstate != PPTP_SESSION_NONE) {577577+ DEBUGP("%s but we already have one",578578+ pptp_msg_name[msg]);579579+ }580580+ info->sstate = PPTP_SESSION_REQUESTED;581581+ break;582582+ case PPTP_STOP_SESSION_REQUEST:583583+ /* client requests end of control session */584584+ info->sstate = PPTP_SESSION_STOPREQ;585585+ break;586586+587587+ case PPTP_OUT_CALL_REQUEST:588588+ if (reqlen < sizeof(_pptpReq.ocreq)) {589589+ DEBUGP("%s: short packet\n", pptp_msg_name[msg]);590590+ /* FIXME: break; */591591+ }592592+593593+ /* client initiating connection to server */594594+ if (info->sstate != PPTP_SESSION_CONFIRMED) {595595+ DEBUGP("%s but no session\n",596596+ pptp_msg_name[msg]);597597+ break;598598+ }599599+ info->cstate = PPTP_CALL_OUT_REQ;600600+ /* track PNS call id */601601+ cid = &pptpReq->ocreq.callID;602602+ DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(*cid));603603+ info->pns_call_id = ntohs(*cid);604604+ break;605605+ case PPTP_IN_CALL_REPLY:606606+ if (reqlen < sizeof(_pptpReq.icack)) {607607+ DEBUGP("%s: short packet\n", pptp_msg_name[msg]);608608+ break;609609+ }610610+611611+ /* client answers incoming call */612612+ if (info->cstate != PPTP_CALL_IN_REQ613613+ && info->cstate != PPTP_CALL_IN_REP) {614614+ DEBUGP("%s without incall_req\n", 615615+ pptp_msg_name[msg]);616616+ break;617617+ }618618+ if (pptpReq->icack.resultCode != PPTP_INCALL_ACCEPT) {619619+ info->cstate = PPTP_CALL_NONE;620620+ break;621621+ }622622+ pcid = &pptpReq->icack.peersCallID;623623+ if (info->pac_call_id != ntohs(*pcid)) {624624+ DEBUGP("%s for unknown call %u\n", 625625+ pptp_msg_name[msg], ntohs(*pcid));626626+ break;627627+ }628628+ DEBUGP("%s, CID=%X\n", pptp_msg_name[msg], ntohs(*pcid));629629+ /* part two of the three-way handshake */630630+ info->cstate = PPTP_CALL_IN_REP;631631+ info->pns_call_id = ntohs(pptpReq->icack.callID);632632+ break;633633+634634+ case PPTP_CALL_CLEAR_REQUEST:635635+ /* client requests hangup of call */636636+ if (info->sstate != PPTP_SESSION_CONFIRMED) {637637+ DEBUGP("CLEAR_CALL but no session\n");638638+ break;639639+ }640640+ /* FUTURE: iterate over all calls and check if641641+ * call ID is valid. We don't do this without newnat,642642+ * because we only know about last call */643643+ info->cstate = PPTP_CALL_CLEAR_REQ;644644+ break;645645+ case PPTP_SET_LINK_INFO:646646+ break;647647+ case PPTP_ECHO_REQUEST:648648+ case PPTP_ECHO_REPLY:649649+ /* I don't have to explain these ;) */650650+ break;651651+ default:652652+ DEBUGP("invalid %s (TY=%d)\n", (msg <= PPTP_MSG_MAX)? 653653+ pptp_msg_name[msg]:pptp_msg_name[0], msg);654654+ /* unknown: no need to create GRE masq table entry */655655+ break;656656+ }657657+658658+ if (ip_nat_pptp_hook_outbound)659659+ return ip_nat_pptp_hook_outbound(pskb, ct, ctinfo, ctlh,660660+ pptpReq);661661+662662+ return NF_ACCEPT;663663+}664664+665665+666666+/* track caller id inside control connection, call expect_related */667667+static int 668668+conntrack_pptp_help(struct sk_buff **pskb,669669+ struct ip_conntrack *ct, enum ip_conntrack_info ctinfo)670670+671671+{672672+ struct pptp_pkt_hdr _pptph, *pptph;673673+ struct tcphdr _tcph, *tcph;674674+ u_int32_t tcplen = (*pskb)->len - (*pskb)->nh.iph->ihl * 4;675675+ u_int32_t datalen;676676+ int dir = CTINFO2DIR(ctinfo);677677+ struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info;678678+ unsigned int nexthdr_off;679679+680680+ int oldsstate, oldcstate;681681+ int ret;682682+683683+ /* don't do any tracking before tcp handshake complete */684684+ if (ctinfo != IP_CT_ESTABLISHED 685685+ && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) {686686+ DEBUGP("ctinfo = %u, skipping\n", ctinfo);687687+ return NF_ACCEPT;688688+ }689689+690690+ nexthdr_off = (*pskb)->nh.iph->ihl*4;691691+ tcph = skb_header_pointer(*pskb, nexthdr_off, sizeof(_tcph), &_tcph);692692+ BUG_ON(!tcph);693693+ nexthdr_off += tcph->doff * 4;694694+ datalen = tcplen - tcph->doff * 4;695695+696696+ if (tcph->fin || tcph->rst) {697697+ DEBUGP("RST/FIN received, timeouting GRE\n");698698+ /* can't do this after real newnat */699699+ info->cstate = PPTP_CALL_NONE;700700+701701+ /* untrack this call id, unexpect GRE packets */702702+ pptp_destroy_siblings(ct);703703+ }704704+705705+ pptph = skb_header_pointer(*pskb, nexthdr_off, sizeof(_pptph), &_pptph);706706+ if (!pptph) {707707+ DEBUGP("no full PPTP header, can't track\n");708708+ return NF_ACCEPT;709709+ }710710+ nexthdr_off += sizeof(_pptph);711711+ datalen -= sizeof(_pptph);712712+713713+ /* if it's not a control message we can't do anything with it */714714+ if (ntohs(pptph->packetType) != PPTP_PACKET_CONTROL ||715715+ ntohl(pptph->magicCookie) != PPTP_MAGIC_COOKIE) {716716+ DEBUGP("not a control packet\n");717717+ return NF_ACCEPT;718718+ }719719+720720+ oldsstate = info->sstate;721721+ oldcstate = info->cstate;722722+723723+ spin_lock_bh(&ip_pptp_lock);724724+725725+ /* FIXME: We just blindly assume that the control connection is always726726+ * established from PNS->PAC. However, RFC makes no guarantee */727727+ if (dir == IP_CT_DIR_ORIGINAL)728728+ /* client -> server (PNS -> PAC) */729729+ ret = pptp_outbound_pkt(pskb, tcph, nexthdr_off, datalen, ct,730730+ ctinfo);731731+ else732732+ /* server -> client (PAC -> PNS) */733733+ ret = pptp_inbound_pkt(pskb, tcph, nexthdr_off, datalen, ct,734734+ ctinfo);735735+ DEBUGP("sstate: %d->%d, cstate: %d->%d\n",736736+ oldsstate, info->sstate, oldcstate, info->cstate);737737+ spin_unlock_bh(&ip_pptp_lock);738738+739739+ return ret;740740+}741741+742742+/* control protocol helper */743743+static struct ip_conntrack_helper pptp = { 744744+ .list = { NULL, NULL },745745+ .name = "pptp", 746746+ .me = THIS_MODULE,747747+ .max_expected = 2,748748+ .timeout = 5 * 60,749749+ .tuple = { .src = { .ip = 0, 750750+ .u = { .tcp = { .port = 751751+ __constant_htons(PPTP_CONTROL_PORT) } } 752752+ }, 753753+ .dst = { .ip = 0, 754754+ .u = { .all = 0 },755755+ .protonum = IPPROTO_TCP756756+ } 757757+ },758758+ .mask = { .src = { .ip = 0, 759759+ .u = { .tcp = { .port = __constant_htons(0xffff) } } 760760+ }, 761761+ .dst = { .ip = 0, 762762+ .u = { .all = 0 },763763+ .protonum = 0xff 764764+ } 765765+ },766766+ .help = conntrack_pptp_help767767+};768768+769769+extern void __exit ip_ct_proto_gre_fini(void);770770+extern int __init ip_ct_proto_gre_init(void);771771+772772+/* ip_conntrack_pptp initialization */773773+static int __init init(void)774774+{775775+ int retcode;776776+777777+ retcode = ip_ct_proto_gre_init();778778+ if (retcode < 0)779779+ return retcode;780780+781781+ DEBUGP(" registering helper\n");782782+ if ((retcode = ip_conntrack_helper_register(&pptp))) {783783+ printk(KERN_ERR "Unable to register conntrack application "784784+ "helper for pptp: %d\n", retcode);785785+ ip_ct_proto_gre_fini();786786+ return retcode;787787+ }788788+789789+ printk("ip_conntrack_pptp version %s loaded\n", IP_CT_PPTP_VERSION);790790+ return 0;791791+}792792+793793+static void __exit fini(void)794794+{795795+ ip_conntrack_helper_unregister(&pptp);796796+ ip_ct_proto_gre_fini();797797+ printk("ip_conntrack_pptp version %s unloaded\n", IP_CT_PPTP_VERSION);798798+}799799+800800+module_init(init);801801+module_exit(fini);802802+803803+EXPORT_SYMBOL(ip_nat_pptp_hook_outbound);804804+EXPORT_SYMBOL(ip_nat_pptp_hook_inbound);805805+EXPORT_SYMBOL(ip_nat_pptp_hook_exp_gre);806806+EXPORT_SYMBOL(ip_nat_pptp_hook_expectfn);
···11+/*22+ * ip_conntrack_proto_gre.c - Version 3.0 33+ *44+ * Connection tracking protocol helper module for GRE.55+ *66+ * GRE is a generic encapsulation protocol, which is generally not very77+ * suited for NAT, as it has no protocol-specific part as port numbers.88+ *99+ * It has an optional key field, which may help us distinguishing two 1010+ * connections between the same two hosts.1111+ *1212+ * GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784 1313+ *1414+ * PPTP is built on top of a modified version of GRE, and has a mandatory1515+ * field called "CallID", which serves us for the same purpose as the key1616+ * field in plain GRE.1717+ *1818+ * Documentation about PPTP can be found in RFC 26371919+ *2020+ * (C) 2000-2005 by Harald Welte <laforge@gnumonks.org>2121+ *2222+ * Development of this code funded by Astaro AG (http://www.astaro.com/)2323+ *2424+ */2525+2626+#include <linux/config.h>2727+#include <linux/module.h>2828+#include <linux/types.h>2929+#include <linux/timer.h>3030+#include <linux/netfilter.h>3131+#include <linux/ip.h>3232+#include <linux/in.h>3333+#include <linux/list.h>3434+3535+static DEFINE_RWLOCK(ip_ct_gre_lock);3636+#define ASSERT_READ_LOCK(x)3737+#define ASSERT_WRITE_LOCK(x)3838+3939+#include <linux/netfilter_ipv4/listhelp.h>4040+#include <linux/netfilter_ipv4/ip_conntrack_protocol.h>4141+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>4242+#include <linux/netfilter_ipv4/ip_conntrack_core.h>4343+4444+#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>4545+#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>4646+4747+MODULE_LICENSE("GPL");4848+MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");4949+MODULE_DESCRIPTION("netfilter connection tracking protocol helper for GRE");5050+5151+/* shamelessly stolen from ip_conntrack_proto_udp.c */5252+#define GRE_TIMEOUT (30*HZ)5353+#define GRE_STREAM_TIMEOUT (180*HZ)5454+5555+#if 05656+#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, __FUNCTION__, ## args)5757+#define DUMP_TUPLE_GRE(x) printk("%u.%u.%u.%u:0x%x -> %u.%u.%u.%u:0x%x\n", \5858+ NIPQUAD((x)->src.ip), ntohs((x)->src.u.gre.key), \5959+ NIPQUAD((x)->dst.ip), ntohs((x)->dst.u.gre.key))6060+#else6161+#define DEBUGP(x, args...)6262+#define DUMP_TUPLE_GRE(x)6363+#endif6464+6565+/* GRE KEYMAP HANDLING FUNCTIONS */6666+static LIST_HEAD(gre_keymap_list);6767+6868+static inline int gre_key_cmpfn(const struct ip_ct_gre_keymap *km,6969+ const struct ip_conntrack_tuple *t)7070+{7171+ return ((km->tuple.src.ip == t->src.ip) &&7272+ (km->tuple.dst.ip == t->dst.ip) &&7373+ (km->tuple.dst.protonum == t->dst.protonum) &&7474+ (km->tuple.dst.u.all == t->dst.u.all));7575+}7676+7777+/* look up the source key for a given tuple */7878+static u_int32_t gre_keymap_lookup(struct ip_conntrack_tuple *t)7979+{8080+ struct ip_ct_gre_keymap *km;8181+ u_int32_t key = 0;8282+8383+ read_lock_bh(&ip_ct_gre_lock);8484+ km = LIST_FIND(&gre_keymap_list, gre_key_cmpfn,8585+ struct ip_ct_gre_keymap *, t);8686+ if (km)8787+ key = km->tuple.src.u.gre.key;8888+ read_unlock_bh(&ip_ct_gre_lock);8989+9090+ DEBUGP("lookup src key 0x%x up key for ", key);9191+ DUMP_TUPLE_GRE(t);9292+9393+ return key;9494+}9595+9696+/* add a single keymap entry, associate with specified master ct */9797+int9898+ip_ct_gre_keymap_add(struct ip_conntrack *ct,9999+ struct ip_conntrack_tuple *t, int reply)100100+{101101+ struct ip_ct_gre_keymap **exist_km, *km, *old;102102+103103+ if (!ct->helper || strcmp(ct->helper->name, "pptp")) {104104+ DEBUGP("refusing to add GRE keymap to non-pptp session\n");105105+ return -1;106106+ }107107+108108+ if (!reply) 109109+ exist_km = &ct->help.ct_pptp_info.keymap_orig;110110+ else111111+ exist_km = &ct->help.ct_pptp_info.keymap_reply;112112+113113+ if (*exist_km) {114114+ /* check whether it's a retransmission */115115+ old = LIST_FIND(&gre_keymap_list, gre_key_cmpfn,116116+ struct ip_ct_gre_keymap *, t);117117+ if (old == *exist_km) {118118+ DEBUGP("retransmission\n");119119+ return 0;120120+ }121121+122122+ DEBUGP("trying to override keymap_%s for ct %p\n", 123123+ reply? "reply":"orig", ct);124124+ return -EEXIST;125125+ }126126+127127+ km = kmalloc(sizeof(*km), GFP_ATOMIC);128128+ if (!km)129129+ return -ENOMEM;130130+131131+ memcpy(&km->tuple, t, sizeof(*t));132132+ *exist_km = km;133133+134134+ DEBUGP("adding new entry %p: ", km);135135+ DUMP_TUPLE_GRE(&km->tuple);136136+137137+ write_lock_bh(&ip_ct_gre_lock);138138+ list_append(&gre_keymap_list, km);139139+ write_unlock_bh(&ip_ct_gre_lock);140140+141141+ return 0;142142+}143143+144144+/* destroy the keymap entries associated with specified master ct */145145+void ip_ct_gre_keymap_destroy(struct ip_conntrack *ct)146146+{147147+ DEBUGP("entering for ct %p\n", ct);148148+149149+ if (!ct->helper || strcmp(ct->helper->name, "pptp")) {150150+ DEBUGP("refusing to destroy GRE keymap to non-pptp session\n");151151+ return;152152+ }153153+154154+ write_lock_bh(&ip_ct_gre_lock);155155+ if (ct->help.ct_pptp_info.keymap_orig) {156156+ DEBUGP("removing %p from list\n", 157157+ ct->help.ct_pptp_info.keymap_orig);158158+ list_del(&ct->help.ct_pptp_info.keymap_orig->list);159159+ kfree(ct->help.ct_pptp_info.keymap_orig);160160+ ct->help.ct_pptp_info.keymap_orig = NULL;161161+ }162162+ if (ct->help.ct_pptp_info.keymap_reply) {163163+ DEBUGP("removing %p from list\n",164164+ ct->help.ct_pptp_info.keymap_reply);165165+ list_del(&ct->help.ct_pptp_info.keymap_reply->list);166166+ kfree(ct->help.ct_pptp_info.keymap_reply);167167+ ct->help.ct_pptp_info.keymap_reply = NULL;168168+ }169169+ write_unlock_bh(&ip_ct_gre_lock);170170+}171171+172172+173173+/* PUBLIC CONNTRACK PROTO HELPER FUNCTIONS */174174+175175+/* invert gre part of tuple */176176+static int gre_invert_tuple(struct ip_conntrack_tuple *tuple,177177+ const struct ip_conntrack_tuple *orig)178178+{179179+ tuple->dst.u.gre.key = orig->src.u.gre.key;180180+ tuple->src.u.gre.key = orig->dst.u.gre.key;181181+182182+ return 1;183183+}184184+185185+/* gre hdr info to tuple */186186+static int gre_pkt_to_tuple(const struct sk_buff *skb,187187+ unsigned int dataoff,188188+ struct ip_conntrack_tuple *tuple)189189+{190190+ struct gre_hdr_pptp _pgrehdr, *pgrehdr;191191+ u_int32_t srckey;192192+ struct gre_hdr _grehdr, *grehdr;193193+194194+ /* first only delinearize old RFC1701 GRE header */195195+ grehdr = skb_header_pointer(skb, dataoff, sizeof(_grehdr), &_grehdr);196196+ if (!grehdr || grehdr->version != GRE_VERSION_PPTP) {197197+ /* try to behave like "ip_conntrack_proto_generic" */198198+ tuple->src.u.all = 0;199199+ tuple->dst.u.all = 0;200200+ return 1;201201+ }202202+203203+ /* PPTP header is variable length, only need up to the call_id field */204204+ pgrehdr = skb_header_pointer(skb, dataoff, 8, &_pgrehdr);205205+ if (!pgrehdr)206206+ return 1;207207+208208+ if (ntohs(grehdr->protocol) != GRE_PROTOCOL_PPTP) {209209+ DEBUGP("GRE_VERSION_PPTP but unknown proto\n");210210+ return 0;211211+ }212212+213213+ tuple->dst.u.gre.key = pgrehdr->call_id;214214+ srckey = gre_keymap_lookup(tuple);215215+ tuple->src.u.gre.key = srckey;216216+217217+ return 1;218218+}219219+220220+/* print gre part of tuple */221221+static int gre_print_tuple(struct seq_file *s,222222+ const struct ip_conntrack_tuple *tuple)223223+{224224+ return seq_printf(s, "srckey=0x%x dstkey=0x%x ", 225225+ ntohs(tuple->src.u.gre.key),226226+ ntohs(tuple->dst.u.gre.key));227227+}228228+229229+/* print private data for conntrack */230230+static int gre_print_conntrack(struct seq_file *s,231231+ const struct ip_conntrack *ct)232232+{233233+ return seq_printf(s, "timeout=%u, stream_timeout=%u ",234234+ (ct->proto.gre.timeout / HZ),235235+ (ct->proto.gre.stream_timeout / HZ));236236+}237237+238238+/* Returns verdict for packet, and may modify conntrack */239239+static int gre_packet(struct ip_conntrack *ct,240240+ const struct sk_buff *skb,241241+ enum ip_conntrack_info conntrackinfo)242242+{243243+ /* If we've seen traffic both ways, this is a GRE connection.244244+ * Extend timeout. */245245+ if (ct->status & IPS_SEEN_REPLY) {246246+ ip_ct_refresh_acct(ct, conntrackinfo, skb,247247+ ct->proto.gre.stream_timeout);248248+ /* Also, more likely to be important, and not a probe. */249249+ set_bit(IPS_ASSURED_BIT, &ct->status);250250+ } else251251+ ip_ct_refresh_acct(ct, conntrackinfo, skb,252252+ ct->proto.gre.timeout);253253+254254+ return NF_ACCEPT;255255+}256256+257257+/* Called when a new connection for this protocol found. */258258+static int gre_new(struct ip_conntrack *ct,259259+ const struct sk_buff *skb)260260+{ 261261+ DEBUGP(": ");262262+ DUMP_TUPLE_GRE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);263263+264264+ /* initialize to sane value. Ideally a conntrack helper265265+ * (e.g. in case of pptp) is increasing them */266266+ ct->proto.gre.stream_timeout = GRE_STREAM_TIMEOUT;267267+ ct->proto.gre.timeout = GRE_TIMEOUT;268268+269269+ return 1;270270+}271271+272272+/* Called when a conntrack entry has already been removed from the hashes273273+ * and is about to be deleted from memory */274274+static void gre_destroy(struct ip_conntrack *ct)275275+{276276+ struct ip_conntrack *master = ct->master;277277+ DEBUGP(" entering\n");278278+279279+ if (!master)280280+ DEBUGP("no master !?!\n");281281+ else282282+ ip_ct_gre_keymap_destroy(master);283283+}284284+285285+/* protocol helper struct */286286+static struct ip_conntrack_protocol gre = { 287287+ .proto = IPPROTO_GRE,288288+ .name = "gre", 289289+ .pkt_to_tuple = gre_pkt_to_tuple,290290+ .invert_tuple = gre_invert_tuple,291291+ .print_tuple = gre_print_tuple,292292+ .print_conntrack = gre_print_conntrack,293293+ .packet = gre_packet,294294+ .new = gre_new,295295+ .destroy = gre_destroy,296296+ .me = THIS_MODULE,297297+#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \298298+ defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)299299+ .tuple_to_nfattr = ip_ct_port_tuple_to_nfattr,300300+ .nfattr_to_tuple = ip_ct_port_nfattr_to_tuple,301301+#endif302302+};303303+304304+/* ip_conntrack_proto_gre initialization */305305+int __init ip_ct_proto_gre_init(void)306306+{307307+ return ip_conntrack_protocol_register(&gre);308308+}309309+310310+void __exit ip_ct_proto_gre_fini(void)311311+{312312+ struct list_head *pos, *n;313313+314314+ /* delete all keymap entries */315315+ write_lock_bh(&ip_ct_gre_lock);316316+ list_for_each_safe(pos, n, &gre_keymap_list) {317317+ DEBUGP("deleting keymap %p at module unload time\n", pos);318318+ list_del(pos);319319+ kfree(pos);320320+ }321321+ write_unlock_bh(&ip_ct_gre_lock);322322+323323+ ip_conntrack_protocol_unregister(&gre); 324324+}325325+326326+EXPORT_SYMBOL(ip_ct_gre_keymap_add);327327+EXPORT_SYMBOL(ip_ct_gre_keymap_destroy);
···11+/*22+ * ip_nat_pptp.c - Version 3.033+ *44+ * NAT support for PPTP (Point to Point Tunneling Protocol).55+ * PPTP is a a protocol for creating virtual private networks.66+ * It is a specification defined by Microsoft and some vendors77+ * working with Microsoft. PPTP is built on top of a modified88+ * version of the Internet Generic Routing Encapsulation Protocol.99+ * GRE is defined in RFC 1701 and RFC 1702. Documentation of1010+ * PPTP can be found in RFC 26371111+ *1212+ * (C) 2000-2005 by Harald Welte <laforge@gnumonks.org>1313+ *1414+ * Development of this code funded by Astaro AG (http://www.astaro.com/)1515+ *1616+ * TODO: - NAT to a unique tuple, not to TCP source port1717+ * (needs netfilter tuple reservation)1818+ *1919+ * Changes:2020+ * 2002-02-10 - Version 1.32121+ * - Use ip_nat_mangle_tcp_packet() because of cloned skb's2222+ * in local connections (Philip Craig <philipc@snapgear.com>)2323+ * - add checks for magicCookie and pptp version2424+ * - make argument list of pptp_{out,in}bound_packet() shorter2525+ * - move to C99 style initializers2626+ * - print version number at module loadtime2727+ * 2003-09-22 - Version 1.52828+ * - use SNATed tcp sourceport as callid, since we get called before2929+ * TCP header is mangled (Philip Craig <philipc@snapgear.com>)3030+ * 2004-10-22 - Version 2.03131+ * - kernel 2.6.x version3232+ * 2005-06-10 - Version 3.03333+ * - kernel >= 2.6.11 version,3434+ * funded by Oxcoda NetBox Blue (http://www.netboxblue.com/)3535+ * 3636+ */3737+3838+#include <linux/config.h>3939+#include <linux/module.h>4040+#include <linux/ip.h>4141+#include <linux/tcp.h>4242+#include <net/tcp.h>4343+4444+#include <linux/netfilter_ipv4/ip_nat.h>4545+#include <linux/netfilter_ipv4/ip_nat_rule.h>4646+#include <linux/netfilter_ipv4/ip_nat_helper.h>4747+#include <linux/netfilter_ipv4/ip_nat_pptp.h>4848+#include <linux/netfilter_ipv4/ip_conntrack_core.h>4949+#include <linux/netfilter_ipv4/ip_conntrack_helper.h>5050+#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>5151+#include <linux/netfilter_ipv4/ip_conntrack_pptp.h>5252+5353+#define IP_NAT_PPTP_VERSION "3.0"5454+5555+MODULE_LICENSE("GPL");5656+MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");5757+MODULE_DESCRIPTION("Netfilter NAT helper module for PPTP");5858+5959+6060+#if 06161+extern const char *pptp_msg_name[];6262+#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, \6363+ __FUNCTION__, ## args)6464+#else6565+#define DEBUGP(format, args...)6666+#endif6767+6868+static void pptp_nat_expected(struct ip_conntrack *ct,6969+ struct ip_conntrack_expect *exp)7070+{7171+ struct ip_conntrack *master = ct->master;7272+ struct ip_conntrack_expect *other_exp;7373+ struct ip_conntrack_tuple t;7474+ struct ip_ct_pptp_master *ct_pptp_info;7575+ struct ip_nat_pptp *nat_pptp_info;7676+7777+ ct_pptp_info = &master->help.ct_pptp_info;7878+ nat_pptp_info = &master->nat.help.nat_pptp_info;7979+8080+ /* And here goes the grand finale of corrosion... */8181+8282+ if (exp->dir == IP_CT_DIR_ORIGINAL) {8383+ DEBUGP("we are PNS->PAC\n");8484+ /* therefore, build tuple for PAC->PNS */8585+ t.src.ip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip;8686+ t.src.u.gre.key = htons(master->help.ct_pptp_info.pac_call_id);8787+ t.dst.ip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip;8888+ t.dst.u.gre.key = htons(master->help.ct_pptp_info.pns_call_id);8989+ t.dst.protonum = IPPROTO_GRE;9090+ } else {9191+ DEBUGP("we are PAC->PNS\n");9292+ /* build tuple for PNS->PAC */9393+ t.src.ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip;9494+ t.src.u.gre.key = 9595+ htons(master->nat.help.nat_pptp_info.pns_call_id);9696+ t.dst.ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip;9797+ t.dst.u.gre.key = 9898+ htons(master->nat.help.nat_pptp_info.pac_call_id);9999+ t.dst.protonum = IPPROTO_GRE;100100+ }101101+102102+ DEBUGP("trying to unexpect other dir: ");103103+ DUMP_TUPLE(&t);104104+ other_exp = ip_conntrack_expect_find(&t);105105+ if (other_exp) {106106+ ip_conntrack_unexpect_related(other_exp);107107+ ip_conntrack_expect_put(other_exp);108108+ DEBUGP("success\n");109109+ } else {110110+ DEBUGP("not found!\n");111111+ }112112+113113+ ip_nat_follow_master(ct, exp);114114+}115115+116116+/* outbound packets == from PNS to PAC */117117+static int118118+pptp_outbound_pkt(struct sk_buff **pskb,119119+ struct ip_conntrack *ct,120120+ enum ip_conntrack_info ctinfo,121121+ struct PptpControlHeader *ctlh,122122+ union pptp_ctrl_union *pptpReq)123123+124124+{125125+ struct ip_ct_pptp_master *ct_pptp_info = &ct->help.ct_pptp_info;126126+ struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info;127127+128128+ u_int16_t msg, *cid = NULL, new_callid;129129+130130+ new_callid = htons(ct_pptp_info->pns_call_id);131131+132132+ switch (msg = ntohs(ctlh->messageType)) {133133+ case PPTP_OUT_CALL_REQUEST:134134+ cid = &pptpReq->ocreq.callID;135135+ /* FIXME: ideally we would want to reserve a call ID136136+ * here. current netfilter NAT core is not able to do137137+ * this :( For now we use TCP source port. This breaks138138+ * multiple calls within one control session */139139+140140+ /* save original call ID in nat_info */141141+ nat_pptp_info->pns_call_id = ct_pptp_info->pns_call_id;142142+143143+ /* don't use tcph->source since we are at a DSTmanip144144+ * hook (e.g. PREROUTING) and pkt is not mangled yet */145145+ new_callid = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.tcp.port;146146+147147+ /* save new call ID in ct info */148148+ ct_pptp_info->pns_call_id = ntohs(new_callid);149149+ break;150150+ case PPTP_IN_CALL_REPLY:151151+ cid = &pptpReq->icreq.callID;152152+ break;153153+ case PPTP_CALL_CLEAR_REQUEST:154154+ cid = &pptpReq->clrreq.callID;155155+ break;156156+ default:157157+ DEBUGP("unknown outbound packet 0x%04x:%s\n", msg,158158+ (msg <= PPTP_MSG_MAX)? 159159+ pptp_msg_name[msg]:pptp_msg_name[0]);160160+ /* fall through */161161+162162+ case PPTP_SET_LINK_INFO:163163+ /* only need to NAT in case PAC is behind NAT box */164164+ case PPTP_START_SESSION_REQUEST:165165+ case PPTP_START_SESSION_REPLY:166166+ case PPTP_STOP_SESSION_REQUEST:167167+ case PPTP_STOP_SESSION_REPLY:168168+ case PPTP_ECHO_REQUEST:169169+ case PPTP_ECHO_REPLY:170170+ /* no need to alter packet */171171+ return NF_ACCEPT;172172+ }173173+174174+ /* only OUT_CALL_REQUEST, IN_CALL_REPLY, CALL_CLEAR_REQUEST pass175175+ * down to here */176176+177177+ IP_NF_ASSERT(cid);178178+179179+ DEBUGP("altering call id from 0x%04x to 0x%04x\n",180180+ ntohs(*cid), ntohs(new_callid));181181+182182+ /* mangle packet */183183+ if (ip_nat_mangle_tcp_packet(pskb, ct, ctinfo,184184+ (void *)cid - ((void *)ctlh - sizeof(struct pptp_pkt_hdr)),185185+ sizeof(new_callid), 186186+ (char *)&new_callid,187187+ sizeof(new_callid)) == 0)188188+ return NF_DROP;189189+190190+ return NF_ACCEPT;191191+}192192+193193+static int194194+pptp_exp_gre(struct ip_conntrack_expect *expect_orig,195195+ struct ip_conntrack_expect *expect_reply)196196+{197197+ struct ip_ct_pptp_master *ct_pptp_info = 198198+ &expect_orig->master->help.ct_pptp_info;199199+ struct ip_nat_pptp *nat_pptp_info = 200200+ &expect_orig->master->nat.help.nat_pptp_info;201201+202202+ struct ip_conntrack *ct = expect_orig->master;203203+204204+ struct ip_conntrack_tuple inv_t;205205+ struct ip_conntrack_tuple *orig_t, *reply_t;206206+207207+ /* save original PAC call ID in nat_info */208208+ nat_pptp_info->pac_call_id = ct_pptp_info->pac_call_id;209209+210210+ /* alter expectation */211211+ orig_t = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;212212+ reply_t = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;213213+214214+ /* alter expectation for PNS->PAC direction */215215+ invert_tuplepr(&inv_t, &expect_orig->tuple);216216+ expect_orig->saved_proto.gre.key = htons(nat_pptp_info->pac_call_id);217217+ expect_orig->tuple.src.u.gre.key = htons(nat_pptp_info->pns_call_id);218218+ expect_orig->tuple.dst.u.gre.key = htons(ct_pptp_info->pac_call_id);219219+ inv_t.src.ip = reply_t->src.ip;220220+ inv_t.dst.ip = reply_t->dst.ip;221221+ inv_t.src.u.gre.key = htons(nat_pptp_info->pac_call_id);222222+ inv_t.dst.u.gre.key = htons(ct_pptp_info->pns_call_id);223223+224224+ if (!ip_conntrack_expect_related(expect_orig)) {225225+ DEBUGP("successfully registered expect\n");226226+ } else {227227+ DEBUGP("can't expect_related(expect_orig)\n");228228+ return 1;229229+ }230230+231231+ /* alter expectation for PAC->PNS direction */232232+ invert_tuplepr(&inv_t, &expect_reply->tuple);233233+ expect_reply->saved_proto.gre.key = htons(nat_pptp_info->pns_call_id);234234+ expect_reply->tuple.src.u.gre.key = htons(nat_pptp_info->pac_call_id);235235+ expect_reply->tuple.dst.u.gre.key = htons(ct_pptp_info->pns_call_id);236236+ inv_t.src.ip = orig_t->src.ip;237237+ inv_t.dst.ip = orig_t->dst.ip;238238+ inv_t.src.u.gre.key = htons(nat_pptp_info->pns_call_id);239239+ inv_t.dst.u.gre.key = htons(ct_pptp_info->pac_call_id);240240+241241+ if (!ip_conntrack_expect_related(expect_reply)) {242242+ DEBUGP("successfully registered expect\n");243243+ } else {244244+ DEBUGP("can't expect_related(expect_reply)\n");245245+ ip_conntrack_unexpect_related(expect_orig);246246+ return 1;247247+ }248248+249249+ if (ip_ct_gre_keymap_add(ct, &expect_reply->tuple, 0) < 0) {250250+ DEBUGP("can't register original keymap\n");251251+ ip_conntrack_unexpect_related(expect_orig);252252+ ip_conntrack_unexpect_related(expect_reply);253253+ return 1;254254+ }255255+256256+ if (ip_ct_gre_keymap_add(ct, &inv_t, 1) < 0) {257257+ DEBUGP("can't register reply keymap\n");258258+ ip_conntrack_unexpect_related(expect_orig);259259+ ip_conntrack_unexpect_related(expect_reply);260260+ ip_ct_gre_keymap_destroy(ct);261261+ return 1;262262+ }263263+264264+ return 0;265265+}266266+267267+/* inbound packets == from PAC to PNS */268268+static int269269+pptp_inbound_pkt(struct sk_buff **pskb,270270+ struct ip_conntrack *ct,271271+ enum ip_conntrack_info ctinfo,272272+ struct PptpControlHeader *ctlh,273273+ union pptp_ctrl_union *pptpReq)274274+{275275+ struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info;276276+ u_int16_t msg, new_cid = 0, new_pcid, *pcid = NULL, *cid = NULL;277277+278278+ int ret = NF_ACCEPT, rv;279279+280280+ new_pcid = htons(nat_pptp_info->pns_call_id);281281+282282+ switch (msg = ntohs(ctlh->messageType)) {283283+ case PPTP_OUT_CALL_REPLY:284284+ pcid = &pptpReq->ocack.peersCallID; 285285+ cid = &pptpReq->ocack.callID;286286+ break;287287+ case PPTP_IN_CALL_CONNECT:288288+ pcid = &pptpReq->iccon.peersCallID;289289+ break;290290+ case PPTP_IN_CALL_REQUEST:291291+ /* only need to nat in case PAC is behind NAT box */292292+ break;293293+ case PPTP_WAN_ERROR_NOTIFY:294294+ pcid = &pptpReq->wanerr.peersCallID;295295+ break;296296+ case PPTP_CALL_DISCONNECT_NOTIFY:297297+ pcid = &pptpReq->disc.callID;298298+ break;299299+ case PPTP_SET_LINK_INFO:300300+ pcid = &pptpReq->setlink.peersCallID;301301+ break;302302+303303+ default:304304+ DEBUGP("unknown inbound packet %s\n", (msg <= PPTP_MSG_MAX)? 305305+ pptp_msg_name[msg]:pptp_msg_name[0]);306306+ /* fall through */307307+308308+ case PPTP_START_SESSION_REQUEST:309309+ case PPTP_START_SESSION_REPLY:310310+ case PPTP_STOP_SESSION_REQUEST:311311+ case PPTP_STOP_SESSION_REPLY:312312+ case PPTP_ECHO_REQUEST:313313+ case PPTP_ECHO_REPLY:314314+ /* no need to alter packet */315315+ return NF_ACCEPT;316316+ }317317+318318+ /* only OUT_CALL_REPLY, IN_CALL_CONNECT, IN_CALL_REQUEST,319319+ * WAN_ERROR_NOTIFY, CALL_DISCONNECT_NOTIFY pass down here */320320+321321+ /* mangle packet */322322+ IP_NF_ASSERT(pcid);323323+ DEBUGP("altering peer call id from 0x%04x to 0x%04x\n",324324+ ntohs(*pcid), ntohs(new_pcid));325325+326326+ rv = ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, 327327+ (void *)pcid - ((void *)ctlh - sizeof(struct pptp_pkt_hdr)),328328+ sizeof(new_pcid), (char *)&new_pcid, 329329+ sizeof(new_pcid));330330+ if (rv != NF_ACCEPT) 331331+ return rv;332332+333333+ if (new_cid) {334334+ IP_NF_ASSERT(cid);335335+ DEBUGP("altering call id from 0x%04x to 0x%04x\n",336336+ ntohs(*cid), ntohs(new_cid));337337+ rv = ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, 338338+ (void *)cid - ((void *)ctlh - sizeof(struct pptp_pkt_hdr)), 339339+ sizeof(new_cid),340340+ (char *)&new_cid, 341341+ sizeof(new_cid));342342+ if (rv != NF_ACCEPT)343343+ return rv;344344+ }345345+346346+ /* check for earlier return value of 'switch' above */347347+ if (ret != NF_ACCEPT)348348+ return ret;349349+350350+ /* great, at least we don't need to resize packets */351351+ return NF_ACCEPT;352352+}353353+354354+355355+extern int __init ip_nat_proto_gre_init(void);356356+extern void __exit ip_nat_proto_gre_fini(void);357357+358358+static int __init init(void)359359+{360360+ int ret;361361+362362+ DEBUGP("%s: registering NAT helper\n", __FILE__);363363+364364+ ret = ip_nat_proto_gre_init();365365+ if (ret < 0)366366+ return ret;367367+368368+ BUG_ON(ip_nat_pptp_hook_outbound);369369+ ip_nat_pptp_hook_outbound = &pptp_outbound_pkt;370370+371371+ BUG_ON(ip_nat_pptp_hook_inbound);372372+ ip_nat_pptp_hook_inbound = &pptp_inbound_pkt;373373+374374+ BUG_ON(ip_nat_pptp_hook_exp_gre);375375+ ip_nat_pptp_hook_exp_gre = &pptp_exp_gre;376376+377377+ BUG_ON(ip_nat_pptp_hook_expectfn);378378+ ip_nat_pptp_hook_expectfn = &pptp_nat_expected;379379+380380+ printk("ip_nat_pptp version %s loaded\n", IP_NAT_PPTP_VERSION);381381+ return 0;382382+}383383+384384+static void __exit fini(void)385385+{386386+ DEBUGP("cleanup_module\n" );387387+388388+ ip_nat_pptp_hook_expectfn = NULL;389389+ ip_nat_pptp_hook_exp_gre = NULL;390390+ ip_nat_pptp_hook_inbound = NULL;391391+ ip_nat_pptp_hook_outbound = NULL;392392+393393+ ip_nat_proto_gre_fini();394394+ /* Make sure noone calls it, meanwhile */395395+ synchronize_net();396396+397397+ printk("ip_nat_pptp version %s unloaded\n", IP_NAT_PPTP_VERSION);398398+}399399+400400+module_init(init);401401+module_exit(fini);
+214
net/ipv4/netfilter/ip_nat_proto_gre.c
···11+/*22+ * ip_nat_proto_gre.c - Version 2.033+ *44+ * NAT protocol helper module for GRE.55+ *66+ * GRE is a generic encapsulation protocol, which is generally not very77+ * suited for NAT, as it has no protocol-specific part as port numbers.88+ *99+ * It has an optional key field, which may help us distinguishing two 1010+ * connections between the same two hosts.1111+ *1212+ * GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784 1313+ *1414+ * PPTP is built on top of a modified version of GRE, and has a mandatory1515+ * field called "CallID", which serves us for the same purpose as the key1616+ * field in plain GRE.1717+ *1818+ * Documentation about PPTP can be found in RFC 26371919+ *2020+ * (C) 2000-2005 by Harald Welte <laforge@gnumonks.org>2121+ *2222+ * Development of this code funded by Astaro AG (http://www.astaro.com/)2323+ *2424+ */2525+2626+#include <linux/config.h>2727+#include <linux/module.h>2828+#include <linux/ip.h>2929+#include <linux/netfilter_ipv4/ip_nat.h>3030+#include <linux/netfilter_ipv4/ip_nat_rule.h>3131+#include <linux/netfilter_ipv4/ip_nat_protocol.h>3232+#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>3333+3434+MODULE_LICENSE("GPL");3535+MODULE_AUTHOR("Harald Welte <laforge@gnumonks.org>");3636+MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE");3737+3838+#if 03939+#define DEBUGP(format, args...) printk(KERN_DEBUG "%s:%s: " format, __FILE__, \4040+ __FUNCTION__, ## args)4141+#else4242+#define DEBUGP(x, args...)4343+#endif4444+4545+/* is key in given range between min and max */4646+static int4747+gre_in_range(const struct ip_conntrack_tuple *tuple,4848+ enum ip_nat_manip_type maniptype,4949+ const union ip_conntrack_manip_proto *min,5050+ const union ip_conntrack_manip_proto *max)5151+{5252+ u_int32_t key;5353+5454+ if (maniptype == IP_NAT_MANIP_SRC)5555+ key = tuple->src.u.gre.key;5656+ else5757+ key = tuple->dst.u.gre.key;5858+5959+ return ntohl(key) >= ntohl(min->gre.key)6060+ && ntohl(key) <= ntohl(max->gre.key);6161+}6262+6363+/* generate unique tuple ... */6464+static int 6565+gre_unique_tuple(struct ip_conntrack_tuple *tuple,6666+ const struct ip_nat_range *range,6767+ enum ip_nat_manip_type maniptype,6868+ const struct ip_conntrack *conntrack)6969+{7070+ static u_int16_t key;7171+ u_int16_t *keyptr;7272+ unsigned int min, i, range_size;7373+7474+ if (maniptype == IP_NAT_MANIP_SRC)7575+ keyptr = &tuple->src.u.gre.key;7676+ else7777+ keyptr = &tuple->dst.u.gre.key;7878+7979+ if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) {8080+ DEBUGP("%p: NATing GRE PPTP\n", conntrack);8181+ min = 1;8282+ range_size = 0xffff;8383+ } else {8484+ min = ntohl(range->min.gre.key);8585+ range_size = ntohl(range->max.gre.key) - min + 1;8686+ }8787+8888+ DEBUGP("min = %u, range_size = %u\n", min, range_size); 8989+9090+ for (i = 0; i < range_size; i++, key++) {9191+ *keyptr = htonl(min + key % range_size);9292+ if (!ip_nat_used_tuple(tuple, conntrack))9393+ return 1;9494+ }9595+9696+ DEBUGP("%p: no NAT mapping\n", conntrack);9797+9898+ return 0;9999+}100100+101101+/* manipulate a GRE packet according to maniptype */102102+static int103103+gre_manip_pkt(struct sk_buff **pskb,104104+ unsigned int iphdroff,105105+ const struct ip_conntrack_tuple *tuple,106106+ enum ip_nat_manip_type maniptype)107107+{108108+ struct gre_hdr *greh;109109+ struct gre_hdr_pptp *pgreh;110110+ struct iphdr *iph = (struct iphdr *)((*pskb)->data + iphdroff);111111+ unsigned int hdroff = iphdroff + iph->ihl*4;112112+113113+ /* pgreh includes two optional 32bit fields which are not required114114+ * to be there. That's where the magic '8' comes from */115115+ if (!skb_make_writable(pskb, hdroff + sizeof(*pgreh)-8))116116+ return 0;117117+118118+ greh = (void *)(*pskb)->data + hdroff;119119+ pgreh = (struct gre_hdr_pptp *) greh;120120+121121+ /* we only have destination manip of a packet, since 'source key' 122122+ * is not present in the packet itself */123123+ if (maniptype == IP_NAT_MANIP_DST) {124124+ /* key manipulation is always dest */125125+ switch (greh->version) {126126+ case 0:127127+ if (!greh->key) {128128+ DEBUGP("can't nat GRE w/o key\n");129129+ break;130130+ }131131+ if (greh->csum) {132132+ /* FIXME: Never tested this code... */133133+ *(gre_csum(greh)) = 134134+ ip_nat_cheat_check(~*(gre_key(greh)),135135+ tuple->dst.u.gre.key,136136+ *(gre_csum(greh)));137137+ }138138+ *(gre_key(greh)) = tuple->dst.u.gre.key;139139+ break;140140+ case GRE_VERSION_PPTP:141141+ DEBUGP("call_id -> 0x%04x\n", 142142+ ntohl(tuple->dst.u.gre.key));143143+ pgreh->call_id = htons(ntohl(tuple->dst.u.gre.key));144144+ break;145145+ default:146146+ DEBUGP("can't nat unknown GRE version\n");147147+ return 0;148148+ break;149149+ }150150+ }151151+ return 1;152152+}153153+154154+/* print out a nat tuple */155155+static unsigned int 156156+gre_print(char *buffer, 157157+ const struct ip_conntrack_tuple *match,158158+ const struct ip_conntrack_tuple *mask)159159+{160160+ unsigned int len = 0;161161+162162+ if (mask->src.u.gre.key)163163+ len += sprintf(buffer + len, "srckey=0x%x ", 164164+ ntohl(match->src.u.gre.key));165165+166166+ if (mask->dst.u.gre.key)167167+ len += sprintf(buffer + len, "dstkey=0x%x ",168168+ ntohl(match->src.u.gre.key));169169+170170+ return len;171171+}172172+173173+/* print a range of keys */174174+static unsigned int 175175+gre_print_range(char *buffer, const struct ip_nat_range *range)176176+{177177+ if (range->min.gre.key != 0 178178+ || range->max.gre.key != 0xFFFF) {179179+ if (range->min.gre.key == range->max.gre.key)180180+ return sprintf(buffer, "key 0x%x ",181181+ ntohl(range->min.gre.key));182182+ else183183+ return sprintf(buffer, "keys 0x%u-0x%u ",184184+ ntohl(range->min.gre.key),185185+ ntohl(range->max.gre.key));186186+ } else187187+ return 0;188188+}189189+190190+/* nat helper struct */191191+static struct ip_nat_protocol gre = { 192192+ .name = "GRE", 193193+ .protonum = IPPROTO_GRE,194194+ .manip_pkt = gre_manip_pkt,195195+ .in_range = gre_in_range,196196+ .unique_tuple = gre_unique_tuple,197197+ .print = gre_print,198198+ .print_range = gre_print_range,199199+#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \200200+ defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)201201+ .range_to_nfattr = ip_nat_port_range_to_nfattr,202202+ .nfattr_to_range = ip_nat_port_nfattr_to_range,203203+#endif204204+};205205+206206+int __init ip_nat_proto_gre_init(void)207207+{208208+ return ip_nat_protocol_register(&gre);209209+}210210+211211+void __exit ip_nat_proto_gre_fini(void)212212+{213213+ ip_nat_protocol_unregister(&gre);214214+}
···3636 * Michal Ostrowski : Module initialization cleanup.3737 * Ulises Alonso : Frame number limit removal and 3838 * packet_set_ring memory leak.3939+ * Eric Biederman : Allow for > 8 byte hardware addresses.4040+ * The convention is that longer addresses4141+ * will simply extend the hardware address4242+ * byte arrays at the end of sockaddr_ll 4343+ * and packet_mreq.3944 *4045 * This program is free software; you can redistribute it and/or4146 * modify it under the terms of the GNU General Public License···166161 int count;167162 unsigned short type;168163 unsigned short alen;169169- unsigned char addr[8];164164+ unsigned char addr[MAX_ADDR_LEN];165165+};166166+/* identical to struct packet_mreq except it has167167+ * a longer address field.168168+ */169169+struct packet_mreq_max170170+{171171+ int mr_ifindex;172172+ unsigned short mr_type;173173+ unsigned short mr_alen;174174+ unsigned char mr_address[MAX_ADDR_LEN];170175};171176#endif172177#ifdef CONFIG_PACKET_MMAP···731716 err = -EINVAL;732717 if (msg->msg_namelen < sizeof(struct sockaddr_ll))733718 goto out;719719+ if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr)))720720+ goto out;734721 ifindex = saddr->sll_ifindex;735722 proto = saddr->sll_protocol;736723 addr = saddr->sll_addr;···761744 if (dev->hard_header) {762745 int res;763746 err = -EINVAL;747747+ if (saddr) {748748+ if (saddr->sll_halen != dev->addr_len)749749+ goto out_free;750750+ if (saddr->sll_hatype != dev->type)751751+ goto out_free;752752+ }764753 res = dev->hard_header(skb, dev, ntohs(proto), addr, NULL, len);765754 if (sock->type != SOCK_DGRAM) {766755 skb->tail = skb->data;···10681045 struct sock *sk = sock->sk;10691046 struct sk_buff *skb;10701047 int copied, err;10481048+ struct sockaddr_ll *sll;1071104910721050 err = -EINVAL;10731051 if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT))···10791055 if (pkt_sk(sk)->ifindex < 0)10801056 return -ENODEV;10811057#endif10821082-10831083- /*10841084- * If the address length field is there to be filled in, we fill10851085- * it in now.10861086- */10871087-10881088- if (sock->type == SOCK_PACKET)10891089- msg->msg_namelen = sizeof(struct sockaddr_pkt);10901090- else10911091- msg->msg_namelen = sizeof(struct sockaddr_ll);1092105810931059 /*10941060 * Call the generic datagram receiver. This handles all sorts···1099108511001086 if(skb==NULL)11011087 goto out;10881088+10891089+ /*10901090+ * If the address length field is there to be filled in, we fill10911091+ * it in now.10921092+ */10931093+10941094+ sll = (struct sockaddr_ll*)skb->cb;10951095+ if (sock->type == SOCK_PACKET)10961096+ msg->msg_namelen = sizeof(struct sockaddr_pkt);10971097+ else10981098+ msg->msg_namelen = sll->sll_halen + offsetof(struct sockaddr_ll, sll_addr);1102109911031100 /*11041101 * You lose any data beyond the buffer you gave. If it worries a···11911166 sll->sll_hatype = 0; /* Bad: we have no ARPHRD_UNSPEC */11921167 sll->sll_halen = 0;11931168 }11941194- *uaddr_len = sizeof(*sll);11691169+ *uaddr_len = offsetof(struct sockaddr_ll, sll_addr) + sll->sll_halen;1195117011961171 return 0;11971172}···12241199 }12251200}1226120112271227-static int packet_mc_add(struct sock *sk, struct packet_mreq *mreq)12021202+static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq)12281203{12291204 struct packet_sock *po = pkt_sk(sk);12301205 struct packet_mclist *ml, *i;···12741249 return err;12751250}1276125112771277-static int packet_mc_drop(struct sock *sk, struct packet_mreq *mreq)12521252+static int packet_mc_drop(struct sock *sk, struct packet_mreq_max *mreq)12781253{12791254 struct packet_mclist *ml, **mlp;12801255···13401315 case PACKET_ADD_MEMBERSHIP: 13411316 case PACKET_DROP_MEMBERSHIP:13421317 {13431343- struct packet_mreq mreq;13441344- if (optlen<sizeof(mreq))13181318+ struct packet_mreq_max mreq;13191319+ int len = optlen;13201320+ memset(&mreq, 0, sizeof(mreq));13211321+ if (len < sizeof(struct packet_mreq))13451322 return -EINVAL;13461346- if (copy_from_user(&mreq,optval,sizeof(mreq)))13231323+ if (len > sizeof(mreq))13241324+ len = sizeof(mreq);13251325+ if (copy_from_user(&mreq,optval,len))13471326 return -EFAULT;13271327+ if (len < (mreq.mr_alen + offsetof(struct packet_mreq, mr_address)))13281328+ return -EINVAL;13481329 if (optname == PACKET_ADD_MEMBERSHIP)13491330 ret = packet_mc_add(sk, &mreq);13501331 else
+11-11
net/sctp/sm_statefuns.c
···24142414 skb_pull(chunk->skb, sizeof(sctp_shutdownhdr_t));24152415 chunk->subh.shutdown_hdr = sdh;2416241624172417+ /* API 5.3.1.5 SCTP_SHUTDOWN_EVENT24182418+ * When a peer sends a SHUTDOWN, SCTP delivers this notification to24192419+ * inform the application that it should cease sending data.24202420+ */24212421+ ev = sctp_ulpevent_make_shutdown_event(asoc, 0, GFP_ATOMIC);24222422+ if (!ev) {24232423+ disposition = SCTP_DISPOSITION_NOMEM;24242424+ goto out; 24252425+ }24262426+ sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));24272427+24172428 /* Upon the reception of the SHUTDOWN, the peer endpoint shall24182429 * - enter the SHUTDOWN-RECEIVED state,24192430 * - stop accepting new data from its SCTP user···24492438 */24502439 sctp_add_cmd_sf(commands, SCTP_CMD_PROCESS_CTSN,24512440 SCTP_U32(chunk->subh.shutdown_hdr->cum_tsn_ack));24522452-24532453- /* API 5.3.1.5 SCTP_SHUTDOWN_EVENT24542454- * When a peer sends a SHUTDOWN, SCTP delivers this notification to24552455- * inform the application that it should cease sending data.24562456- */24572457- ev = sctp_ulpevent_make_shutdown_event(asoc, 0, GFP_ATOMIC);24582458- if (!ev) {24592459- disposition = SCTP_DISPOSITION_NOMEM;24602460- goto out; 24612461- }24622462- sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev));2463244124642442out:24652443 return disposition;