···3279S: Spain32803281N: Linus Torvalds3282-E: torvalds@osdl.org3283D: Original kernel hacker3284S: 12725 SW Millikan Way, Suite 4003285S: Beaverton, Oregon 97005
···3279S: Spain32803281N: Linus Torvalds3282+E: torvalds@linux-foundation.org3283D: Original kernel hacker3284S: 12725 SW Millikan Way, Suite 4003285S: Beaverton, Oregon 97005
+4
Documentation/SubmitChecklist
···7273 If the new code is substantial, addition of subsystem-specific fault74 injection might be appropriate.0000
···7273 If the new code is substantial, addition of subsystem-specific fault74 injection might be appropriate.75+76+22: Newly-added code has been compiled with `gcc -W'. This will generate77+ lots of noise, but is good for finding bugs like "warning: comparison78+ between signed and unsigned".
+3-3
Documentation/SubmittingPatches
···134135136Linus Torvalds is the final arbiter of all changes accepted into the137-Linux kernel. His e-mail address is <torvalds@osdl.org>. He gets138-a lot of e-mail, so typically you should do your best to -avoid- sending139-him e-mail.140141Patches which are bug fixes, are "obvious" changes, or similarly142require little discussion should be sent or CC'd to Linus. Patches
···134135136Linus Torvalds is the final arbiter of all changes accepted into the137+Linux kernel. His e-mail address is <torvalds@linux-foundation.org>. 138+He gets a lot of e-mail, so typically you should do your best to -avoid-139+sending him e-mail. 140141Patches which are bug fixes, are "obvious" changes, or similarly142require little discussion should be sent or CC'd to Linus. Patches
+7
Documentation/feature-removal-schedule.txt
···318Who: Len Brown <len.brown@intel.com>319320---------------------------0000000
···318Who: Len Brown <len.brown@intel.com>319320---------------------------321+322+What: JFFS (version 1)323+When: 2.6.21324+Why: Unmaintained for years, superceded by JFFS2 for years.325+Who: Jeff Garzik <jeff@garzik.org>326+327+---------------------------
+38-11
Documentation/kdump/kdump.txt
···17memory image to a dump file on the local disk, or across the network to18a remote system.1920-Kdump and kexec are currently supported on the x86, x86_64, ppc64 and IA6421architectures.2223When the system kernel boots, it reserves a small section of memory for···61622) Download the kexec-tools user-space package from the following URL:6364-http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/kexec-tools-testing-20061214.tar.gz000006566Note: Latest kexec-tools-testing git tree is available at67···76773) Unpack the tarball with the tar command, as follows:7879- tar xvpzf kexec-tools-testing-20061214.tar.gz8081-4) Change to the kexec-tools-1.101 directory, as follows:8283- cd kexec-tools-testing-2006121484855) Configure the package, as follows:86···229230Dump-capture kernel config options (Arch Dependent, ia64)231----------------------------------------------------------232-(To be filled)0000000000000000233234235Boot into System Kernel···263 On x86 and x86_64, use "crashkernel=64M@16M".264265 On ppc64, use "crashkernel=128M@32M".0000266267Load the Dump-capture Kernel268============================···286For ppc64:287 - Use vmlinux288For ia64:289- (To be filled)0290291If you are using a uncompressed vmlinux image then use following command292to load dump-capture kernel.···303 --initrd=<initrd-for-dump-capture-kernel> \304 --append="root=<root-dev> <arch-specific-options>"3050000306Following are the arch specific command line options to be used while307loading dump-capture kernel.308309-For i386 and x86_64:310 "init 1 irqpoll maxcpus=1"311312For ppc64:313 "init 1 maxcpus=1 noirqdistrib"314-315-For IA64316- (To be filled)317318319Notes on loading the dump-capture kernel:
···17memory image to a dump file on the local disk, or across the network to18a remote system.1920+Kdump and kexec are currently supported on the x86, x86_64, ppc64 and ia6421architectures.2223When the system kernel boots, it reserves a small section of memory for···61622) Download the kexec-tools user-space package from the following URL:6364+http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/kexec-tools-testing.tar.gz65+66+This is a symlink to the latest version, which at the time of writing is67+20061214, the only release of kexec-tools-testing so far. As other versions68+are made released, the older onese will remain available at69+http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/7071Note: Latest kexec-tools-testing git tree is available at72···71723) Unpack the tarball with the tar command, as follows:7374+ tar xvpzf kexec-tools-testing.tar.gz7576+4) Change to the kexec-tools directory, as follows:7778+ cd kexec-tools-testing-VERSION79805) Configure the package, as follows:81···224225Dump-capture kernel config options (Arch Dependent, ia64)226----------------------------------------------------------227+228+- No specific options are required to create a dump-capture kernel229+ for ia64, other than those specified in the arch idependent section230+ above. This means that it is possible to use the system kernel231+ as a dump-capture kernel if desired.232+233+ The crashkernel region can be automatically placed by the system234+ kernel at run time. This is done by specifying the base address as 0,235+ or omitting it all together.236+237+ crashkernel=256M@0238+ or239+ crashkernel=256M240+241+ If the start address is specified, note that the start address of the242+ kernel will be aligned to 64Mb, so if the start address is not then243+ any space below the alignment point will be wasted.244245246Boot into System Kernel···242 On x86 and x86_64, use "crashkernel=64M@16M".243244 On ppc64, use "crashkernel=128M@32M".245+246+ On ia64, 256M@256M is a generous value that typically works.247+ The region may be automatically placed on ia64, see the248+ dump-capture kernel config option notes above.249250Load the Dump-capture Kernel251============================···261For ppc64:262 - Use vmlinux263For ia64:264+ - Use vmlinux or vmlinuz.gz265+266267If you are using a uncompressed vmlinux image then use following command268to load dump-capture kernel.···277 --initrd=<initrd-for-dump-capture-kernel> \278 --append="root=<root-dev> <arch-specific-options>"279280+Please note, that --args-linux does not need to be specified for ia64.281+It is planned to make this a no-op on that architecture, but for now282+it should be omitted283+284Following are the arch specific command line options to be used while285loading dump-capture kernel.286287+For i386, x86_64 and ia64:288 "init 1 irqpoll maxcpus=1"289290For ppc64:291 "init 1 maxcpus=1 noirqdistrib"000292293294Notes on loading the dump-capture kernel:
+549-153
Documentation/pci.txt
···1- How To Write Linux PCI Drivers23- by Martin Mares <mj@ucw.cz> on 07-Feb-200000045~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~6-The world of PCI is vast and it's full of (mostly unpleasant) surprises.7-Different PCI devices have different requirements and different bugs --8-because of this, the PCI support layer in Linux kernel is not as trivial9-as one would wish. This short pamphlet tries to help all potential driver10-authors find their way through the deep forests of PCI handling.000000000000001112130. Structure of PCI drivers14~~~~~~~~~~~~~~~~~~~~~~~~~~~15-There exist two kinds of PCI drivers: new-style ones (which leave most of16-probing for devices to the PCI layer and support online insertion and removal17-of devices [thus supporting PCI, hot-pluggable PCI and CardBus in a single18-driver]) and old-style ones which just do all the probing themselves. Unless19-you have a very good reason to do so, please don't use the old way of probing20-in any new code. After the driver finds the devices it wishes to operate21-on (either the old or the new way), it needs to perform the following steps:0000002223 Enable the device24- Access device configuration space25- Discover resources (addresses and IRQ numbers) provided by the device26- Allocate these resources27- Communicate with the device00000000000028 Disable the device2930-Most of these topics are covered by the following sections, for the rest31-look at <linux/pci.h>, it's hopefully well commented.3233If the PCI subsystem is not configured (CONFIG_PCI is not set), most of34-the functions described below are defined as inline functions either completely35-empty or just returning an appropriate error codes to avoid lots of ifdefs36-in the drivers.373839-1. New-style drivers40-~~~~~~~~~~~~~~~~~~~~41-The new-style drivers just call pci_register_driver during their initialization42-with a pointer to a structure describing the driver (struct pci_driver) which43-contains:4445- name Name of the driver0000000046 id_table Pointer to table of device ID's the driver is47 interested in. Most drivers should export this48 table using MODULE_DEVICE_TABLE(pci,...).49- probe Pointer to a probing function which gets called (during50- execution of pci_register_driver for already existing51- devices or later if a new device gets inserted) for all52- PCI devices which match the ID table and are not handled53- by the other drivers yet. This function gets passed a54- pointer to the pci_dev structure representing the device55- and also which entry in the ID table did the device56- match. It returns zero when the driver has accepted the57- device or an error code (negative number) otherwise.58- This function always gets called from process context,59- so it can sleep.60- remove Pointer to a function which gets called whenever a61- device being handled by this driver is removed (either62- during deregistration of the driver or when it's63- manually pulled out of a hot-pluggable slot). This64- function always gets called from process context, so it65- can sleep.66- save_state Save a device's state before it's suspend.00067 suspend Put device into low power state.00068 resume Wake device from low power state.000069 enable_wake Enable device to generate wake events from a low power70 state.7172- (Please see Documentation/power/pci.txt for descriptions73- of PCI Power Management and the related functions)0007475-The ID table is an array of struct pci_device_id ending with a all-zero entry.76-Each entry consists of:7778- vendor, device Vendor and device ID to match (or PCI_ANY_ID)00000000079 subvendor, Subsystem vendor and device ID to match (or PCI_ANY_ID)80- subdevice81- class, Device class to match. The class_mask tells which bits82- class_mask of the class are honored during the comparison.0000000083 driver_data Data private to the driver.00008485-Most drivers don't need to use the driver_data field. Best practice86-for use of driver_data is to use it as an index into a static list of87-equivalent device types, not to use it as a pointer.8889-Have a table entry {PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID}90-to have probe() called for every PCI device known to the system.9192-New PCI IDs may be added to a device driver at runtime by writing93-to the file /sys/bus/pci/drivers/{driver}/new_id. When added, the94-driver will probe for all devices it can support.9596echo "vendor device subvendor subdevice class class_mask driver_data" > \97- /sys/bus/pci/drivers/{driver}/new_id98-where all fields are passed in as hexadecimal values (no leading 0x).99-Users need pass only as many fields as necessary; vendor, device,100-subvendor, and subdevice fields default to PCI_ANY_ID (FFFFFFFF),101-class and classmask fields default to 0, and driver_data defaults to102-0UL. Device drivers must initialize use_driver_data in the dynids struct103-in their pci_driver struct prior to calling pci_register_driver in order104-for the driver_data field to get passed to the driver. Otherwise, only a105-0 is passed in that field.00106107When the driver exits, it just calls pci_unregister_driver() and the PCI layer108automatically calls the remove hook for all devices handled by the driver.000109110Please mark the initialization and cleanup functions where appropriate111(the corresponding macros are defined in <linux/init.h>):···184 __init Initialization code. Thrown away after the driver185 initializes.186 __exit Exit code. Ignored for non-modular drivers.187- __devinit Device initialization code. Identical to __init if188- the kernel is not compiled with CONFIG_HOTPLUG, normal189- function otherwise.00190 __devexit The same for __exit.191192-Tips:193- The module_init()/module_exit() functions (and all initialization194- functions called only from these) should be marked __init/exit.195- The struct pci_driver shouldn't be marked with any of these tags.196- The ID table array should be marked __devinitdata.197- The probe() and remove() functions (and all initialization198- functions called only from these) should be marked __devinit/exit.199- If you are sure the driver is not a hotplug driver then use only 200- __init/exit __initdata/exitdata.201202- Pointers to functions marked as __devexit must be created using203- __devexit_p(function_name). That will generate the function204- name or NULL if the __devexit function will be discarded.00000000000000205206207-2. How to find PCI devices manually (the old style)208-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~209-PCI drivers not using the pci_register_driver() interface search210-for PCI devices manually using the following constructs:0000000211212Searching by vendor and device ID:213···239240Searching by both vendor/device and subsystem vendor/device ID:241242- pci_get_subsys(VENDOR_ID, DEVICE_ID, SUBSYS_VENDOR_ID, SUBSYS_DEVICE_ID, dev).243244- You can use the constant PCI_ANY_ID as a wildcard replacement for245VENDOR_ID or DEVICE_ID. This allows searching for any device from a246specific vendor, for example.247248- These functions are hotplug-safe. They increment the reference count on249the pci_dev that they return. You must eventually (possibly at module unload)250decrement the reference count on these devices by calling pci_dev_put().251252253-3. Enabling and disabling devices254-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~255- Before you do anything with the device you've found, you need to enable256-it by calling pci_enable_device() which enables I/O and memory regions of257-the device, allocates an IRQ if necessary, assigns missing resources if258-needed and wakes up the device if it was in suspended state. Please note259-that this function can fail.260261- If you want to use the device in bus mastering mode, call pci_set_master()262-which enables the bus master bit in PCI_COMMAND register and also fixes263-the latency timer value if it's set to something bogus by the BIOS.264265- If you want to use the PCI Memory-Write-Invalidate transaction,000000000000000000000000000000000000000000000266call pci_set_mwi(). This enables the PCI_COMMAND bit for Mem-Wr-Inval267and also ensures that the cache line size register is set correctly.268-Make sure to check the return value of pci_set_mwi(), not all architectures269-may support Memory-Write-Invalidate.270271- If your driver decides to stop using the device (e.g., there was an272-error while setting it up or the driver module is being unloaded), it273-should call pci_disable_device() to deallocate any IRQ resources, disable274-PCI bus-mastering, etc. You should not do anything with the device after0000000000275calling pci_disable_device().0276277-4. How to access PCI config space00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000278~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~279- You can use pci_(read|write)_config_(byte|word|dword) to access the config0280space of a device represented by struct pci_dev *. All these functions return 0281when successful or an error code (PCIBIOS_...) which can be translated to a text282string by pcibios_strerror. Most drivers expect that accesses to valid PCI283devices don't fail.284285- If you don't have a struct pci_dev available, you can call286pci_bus_(read|write)_config_(byte|word|dword) to access a given device287and function on that bus.288289- If you access fields in the standard portion of the config header, please290use symbolic names of locations and bits declared in <linux/pci.h>.291292- If you need to access Extended PCI Capability registers, just call293pci_find_capability() for the particular capability and it will find the294corresponding register block for you.295296297-5. Addresses and interrupts298-~~~~~~~~~~~~~~~~~~~~~~~~~~~299- Memory and port addresses and interrupt numbers should NOT be read from the300-config space. You should use the values in the pci_dev structure as they might301-have been remapped by the kernel.302-303- See Documentation/IO-mapping.txt for how to access device memory.304-305- The device driver needs to call pci_request_region() to make sure306-no other device is already using the same resource. The driver is expected307-to determine MMIO and IO Port resource availability _before_ calling308-pci_enable_device(). Conversely, drivers should call pci_release_region()309-_after_ calling pci_disable_device(). The idea is to prevent two devices310-colliding on the same address range.311-312-Generic flavors of pci_request_region() are request_mem_region()313-(for MMIO ranges) and request_region() (for IO Port ranges).314-Use these for address resources that are not described by "normal" PCI315-interfaces (e.g. BAR).316-317- All interrupt handlers should be registered with IRQF_SHARED and use the devid318-to map IRQs to devices (remember that all PCI interrupts are shared).319-3203216. Other interesting functions322~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~0323pci_find_slot() Find pci_dev corresponding to given bus and324 slot numbers.325pci_set_power_state() Set PCI Power Management state (0=D0 ... 3=D3)···560pci_clear_mwi() Disable Memory-Write-Invalidate transactions.56156205637. Miscellaneous hints564~~~~~~~~~~~~~~~~~~~~~~565-When displaying PCI slot names to the user (for example when a driver wants566-to tell the user what card has it found), please use pci_name(pci_dev)567-for this purpose.568569Always refer to the PCI devices by a pointer to the pci_dev structure.570All PCI layer functions use this identification and it's the only···573special purposes -- on systems with multiple primary buses their semantics574can be pretty complex.575576-If you're going to use PCI bus mastering DMA, take a look at577-Documentation/DMA-mapping.txt.578-579Don't try to turn on Fast Back to Back writes in your driver. All devices580on the bus need to be capable of doing it, so this is something which needs581to be handled by platform and generic code, not individual drivers.58258305848. Vendor and device identifications585~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~586-For the future, let's avoid adding device ids to include/linux/pci_ids.h.587588-PCI_VENDOR_ID_xxx for vendors, and a hex constant for device ids.0589590-Rationale: PCI_VENDOR_ID_xxx constants are re-used, but device ids are not.591- Further, device ids are arbitrary hex numbers, normally used only in a592- single location, the pci_device_id table.00005935949. Obsolete functions595~~~~~~~~~~~~~~~~~~~~~0596There are several functions which you might come across when trying to597port an old driver to the new PCI interface. They are no longer present598in the kernel as they aren't compatible with hotplug or PCI domains or599having sane locking.600601-pci_find_device() Superseded by pci_get_device()602-pci_find_subsys() Superseded by pci_get_subsys()603-pci_find_slot() Superseded by pci_get_slot()0000000000000000000000000000000000000000000000000000000000000000000000000000000
···012+ How To Write Linux PCI Drivers3+4+ by Martin Mares <mj@ucw.cz> on 07-Feb-20005+ updated by Grant Grundler <grundler@parisc-linux.org> on 23-Dec-200667~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~8+The world of PCI is vast and full of (mostly unpleasant) surprises.9+Since each CPU architecture implements different chip-sets and PCI devices10+have different requirements (erm, "features"), the result is the PCI support11+in the Linux kernel is not as trivial as one would wish. This short paper12+tries to introduce all potential driver authors to Linux APIs for13+PCI device drivers.14+15+A more complete resource is the third edition of "Linux Device Drivers"16+by Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman.17+LDD3 is available for free (under Creative Commons License) from:18+19+ http://lwn.net/Kernel/LDD3/20+21+However, keep in mind that all documents are subject to "bit rot".22+Refer to the source code if things are not working as described here.23+24+Please send questions/comments/patches about Linux PCI API to the25+"Linux PCI" <linux-pci@atrey.karlin.mff.cuni.cz> mailing list.26+2728290. Structure of PCI drivers30~~~~~~~~~~~~~~~~~~~~~~~~~~~31+PCI drivers "discover" PCI devices in a system via pci_register_driver().32+Actually, it's the other way around. When the PCI generic code discovers33+a new device, the driver with a matching "description" will be notified.34+Details on this below.35+36+pci_register_driver() leaves most of the probing for devices to37+the PCI layer and supports online insertion/removal of devices [thus38+supporting hot-pluggable PCI, CardBus, and Express-Card in a single driver].39+pci_register_driver() call requires passing in a table of function40+pointers and thus dictates the high level structure of a driver.41+42+Once the driver knows about a PCI device and takes ownership, the43+driver generally needs to perform the following initialization:4445 Enable the device46+ Request MMIO/IOP resources47+ Set the DMA mask size (for both coherent and streaming DMA)48+ Allocate and initialize shared control data (pci_allocate_coherent())49+ Access device configuration space (if needed)50+ Register IRQ handler (request_irq())51+ Initialize non-PCI (i.e. LAN/SCSI/etc parts of the chip)52+ Enable DMA/processing engines53+54+When done using the device, and perhaps the module needs to be unloaded,55+the driver needs to take the follow steps:56+ Disable the device from generating IRQs57+ Release the IRQ (free_irq())58+ Stop all DMA activity59+ Release DMA buffers (both streaming and coherent)60+ Unregister from other subsystems (e.g. scsi or netdev)61+ Release MMIO/IOP resources62 Disable the device6364+Most of these topics are covered in the following sections.65+For the rest look at LDD3 or <linux/pci.h> .6667If the PCI subsystem is not configured (CONFIG_PCI is not set), most of68+the PCI functions described below are defined as inline functions either69+completely empty or just returning an appropriate error codes to avoid70+lots of ifdefs in the drivers.7172000007374+1. pci_register_driver() call75+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~76+77+PCI device drivers call pci_register_driver() during their78+initialization with a pointer to a structure describing the driver79+(struct pci_driver):80+81+ field name Description82+ ---------- ------------------------------------------------------83 id_table Pointer to table of device ID's the driver is84 interested in. Most drivers should export this85 table using MODULE_DEVICE_TABLE(pci,...).86+87+ probe This probing function gets called (during execution88+ of pci_register_driver() for already existing89+ devices or later if a new device gets inserted) for90+ all PCI devices which match the ID table and are not91+ "owned" by the other drivers yet. This function gets92+ passed a "struct pci_dev *" for each device whose93+ entry in the ID table matches the device. The probe94+ function returns zero when the driver chooses to95+ take "ownership" of the device or an error code96+ (negative number) otherwise.97+ The probe function always gets called from process98+ context, so it can sleep.99+100+ remove The remove() function gets called whenever a device101+ being handled by this driver is removed (either during102+ deregistration of the driver or when it's manually103+ pulled out of a hot-pluggable slot).104+ The remove function always gets called from process105+ context, so it can sleep.106+107 suspend Put device into low power state.108+ suspend_late Put device into low power state.109+110+ resume_early Wake device from low power state.111 resume Wake device from low power state.112+113+ (Please see Documentation/power/pci.txt for descriptions114+ of PCI Power Management and the related functions.)115+116 enable_wake Enable device to generate wake events from a low power117 state.118119+ shutdown Hook into reboot_notifier_list (kernel/sys.c).120+ Intended to stop any idling DMA operations.121+ Useful for enabling wake-on-lan (NIC) or changing122+ the power state of a device before reboot.123+ e.g. drivers/net/e100.c.124125+ err_handler See Documentation/pci-error-recovery.txt0126127+ multithread_probe Enable multi-threaded probe/scan. Driver must128+ provide its own locking/syncronization for init129+ operations if this is enabled.130+131+132+The ID table is an array of struct pci_device_id entries ending with an133+all-zero entry. Each entry consists of:134+135+ vendor,device Vendor and device ID to match (or PCI_ANY_ID)136+137 subvendor, Subsystem vendor and device ID to match (or PCI_ANY_ID)138+ subdevice,139+140+ class Device class, subclass, and "interface" to match.141+ See Appendix D of the PCI Local Bus Spec or142+ include/linux/pci_ids.h for a full list of classes.143+ Most drivers do not need to specify class/class_mask144+ as vendor/device is normally sufficient.145+146+ class_mask limit which sub-fields of the class field are compared.147+ See drivers/scsi/sym53c8xx_2/ for example of usage.148+149 driver_data Data private to the driver.150+ Most drivers don't need to use driver_data field.151+ Best practice is to use driver_data as an index152+ into a static list of equivalent device types,153+ instead of using it as a pointer.154000155156+Most drivers only need PCI_DEVICE() or PCI_DEVICE_CLASS() to set up157+a pci_device_id table.158159+New PCI IDs may be added to a device driver pci_ids table at runtime160+as shown below:0161162echo "vendor device subvendor subdevice class class_mask driver_data" > \163+/sys/bus/pci/drivers/{driver}/new_id164+165+All fields are passed in as hexadecimal values (no leading 0x).166+Users need pass only as many fields as necessary:167+ o vendor, device, subvendor, and subdevice fields default168+ to PCI_ANY_ID (FFFFFFFF),169+ o class and classmask fields default to 0170+ o driver_data defaults to 0UL.171+172+Once added, the driver probe routine will be invoked for any unclaimed173+PCI devices listed in its (newly updated) pci_ids list.174175When the driver exits, it just calls pci_unregister_driver() and the PCI layer176automatically calls the remove hook for all devices handled by the driver.177+178+179+1.1 "Attributes" for driver functions/data180181Please mark the initialization and cleanup functions where appropriate182(the corresponding macros are defined in <linux/init.h>):···113 __init Initialization code. Thrown away after the driver114 initializes.115 __exit Exit code. Ignored for non-modular drivers.116+117+118+ __devinit Device initialization code.119+ Identical to __init if the kernel is not compiled120+ with CONFIG_HOTPLUG, normal function otherwise.121 __devexit The same for __exit.122123+Tips on when/where to use the above attributes:124+ o The module_init()/module_exit() functions (and all125+ initialization functions called _only_ from these)126+ should be marked __init/__exit.00000127128+ o Do not mark the struct pci_driver.129+130+ o The ID table array should be marked __devinitdata.131+132+ o The probe() and remove() functions should be marked __devinit133+ and __devexit respectively. All initialization functions134+ exclusively called by the probe() routine, can be marked __devinit.135+ Ditto for remove() and __devexit.136+137+ o If mydriver_probe() is marked with __devinit(), then all address138+ references to mydriver_probe must use __devexit_p(mydriver_probe)139+ (in the struct pci_driver declaration for example).140+ __devexit_p() will generate the function name _or_ NULL if the141+ function will be discarded. For an example, see drivers/net/tg3.c.142+143+ o Do NOT mark a function if you are not sure which mark to use.144+ Better to not mark the function than mark the function wrong.145146147+148+2. How to find PCI devices manually149+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~150+151+PCI drivers should have a really good reason for not using the152+pci_register_driver() interface to search for PCI devices.153+The main reason PCI devices are controlled by multiple drivers154+is because one PCI device implements several different HW services.155+E.g. combined serial/parallel port/floppy controller.156+157+A manual search may be performed using the following constructs:158159Searching by vendor and device ID:160···150151Searching by both vendor/device and subsystem vendor/device ID:152153+ pci_get_subsys(VENDOR_ID,DEVICE_ID, SUBSYS_VENDOR_ID, SUBSYS_DEVICE_ID, dev).154155+You can use the constant PCI_ANY_ID as a wildcard replacement for156VENDOR_ID or DEVICE_ID. This allows searching for any device from a157specific vendor, for example.158159+These functions are hotplug-safe. They increment the reference count on160the pci_dev that they return. You must eventually (possibly at module unload)161decrement the reference count on these devices by calling pci_dev_put().1621630000000164165+3. Device Initialization Steps166+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~0167168+As noted in the introduction, most PCI drivers need the following steps169+for device initialization:170+171+ Enable the device172+ Request MMIO/IOP resources173+ Set the DMA mask size (for both coherent and streaming DMA)174+ Allocate and initialize shared control data (pci_allocate_coherent())175+ Access device configuration space (if needed)176+ Register IRQ handler (request_irq())177+ Initialize non-PCI (i.e. LAN/SCSI/etc parts of the chip)178+ Enable DMA/processing engines.179+180+The driver can access PCI config space registers at any time.181+(Well, almost. When running BIST, config space can go away...but182+that will just result in a PCI Bus Master Abort and config reads183+will return garbage).184+185+186+3.1 Enable the PCI device187+~~~~~~~~~~~~~~~~~~~~~~~~~188+Before touching any device registers, the driver needs to enable189+the PCI device by calling pci_enable_device(). This will:190+ o wake up the device if it was in suspended state,191+ o allocate I/O and memory regions of the device (if BIOS did not),192+ o allocate an IRQ (if BIOS did not).193+194+NOTE: pci_enable_device() can fail! Check the return value.195+NOTE2: Also see pci_enable_device_bars() below. Drivers can196+ attempt to enable only a subset of BARs they need.197+198+[ OS BUG: we don't check resource allocations before enabling those199+ resources. The sequence would make more sense if we called200+ pci_request_resources() before calling pci_enable_device().201+ Currently, the device drivers can't detect the bug when when two202+ devices have been allocated the same range. This is not a common203+ problem and unlikely to get fixed soon.204+205+ This has been discussed before but not changed as of 2.6.19:206+ http://lkml.org/lkml/2006/3/2/194207+]208+209+pci_set_master() will enable DMA by setting the bus master bit210+in the PCI_COMMAND register. It also fixes the latency timer value if211+it's set to something bogus by the BIOS.212+213+If the PCI device can use the PCI Memory-Write-Invalidate transaction,214call pci_set_mwi(). This enables the PCI_COMMAND bit for Mem-Wr-Inval215and also ensures that the cache line size register is set correctly.216+Check the return value of pci_set_mwi() as not all architectures217+or chip-sets may support Memory-Write-Invalidate.218219+220+3.2 Request MMIO/IOP resources221+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~222+Memory (MMIO), and I/O port addresses should NOT be read directly223+from the PCI device config space. Use the values in the pci_dev structure224+as the PCI "bus address" might have been remapped to a "host physical"225+address by the arch/chip-set specific kernel support.226+227+See Documentation/IO-mapping.txt for how to access device registers228+or device memory.229+230+The device driver needs to call pci_request_region() to verify231+no other device is already using the same address resource.232+Conversely, drivers should call pci_release_region() AFTER233calling pci_disable_device().234+The idea is to prevent two devices colliding on the same address range.235236+[ See OS BUG comment above. Currently (2.6.19), The driver can only237+ determine MMIO and IO Port resource availability _after_ calling238+ pci_enable_device(). ]239+240+Generic flavors of pci_request_region() are request_mem_region()241+(for MMIO ranges) and request_region() (for IO Port ranges).242+Use these for address resources that are not described by "normal" PCI243+BARs.244+245+Also see pci_request_selected_regions() below.246+247+248+3.3 Set the DMA mask size249+~~~~~~~~~~~~~~~~~~~~~~~~~250+[ If anything below doesn't make sense, please refer to251+ Documentation/DMA-API.txt. This section is just a reminder that252+ drivers need to indicate DMA capabilities of the device and is not253+ an authoritative source for DMA interfaces. ]254+255+While all drivers should explicitly indicate the DMA capability256+(e.g. 32 or 64 bit) of the PCI bus master, devices with more than257+32-bit bus master capability for streaming data need the driver258+to "register" this capability by calling pci_set_dma_mask() with259+appropriate parameters. In general this allows more efficient DMA260+on systems where System RAM exists above 4G _physical_ address.261+262+Drivers for all PCI-X and PCIe compliant devices must call263+pci_set_dma_mask() as they are 64-bit DMA devices.264+265+Similarly, drivers must also "register" this capability if the device266+can directly address "consistent memory" in System RAM above 4G physical267+address by calling pci_set_consistent_dma_mask().268+Again, this includes drivers for all PCI-X and PCIe compliant devices.269+Many 64-bit "PCI" devices (before PCI-X) and some PCI-X devices are270+64-bit DMA capable for payload ("streaming") data but not control271+("consistent") data.272+273+274+3.4 Setup shared control data275+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~276+Once the DMA masks are set, the driver can allocate "consistent" (a.k.a. shared)277+memory. See Documentation/DMA-API.txt for a full description of278+the DMA APIs. This section is just a reminder that it needs to be done279+before enabling DMA on the device.280+281+282+3.5 Initialize device registers283+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~284+Some drivers will need specific "capability" fields programmed285+or other "vendor specific" register initialized or reset.286+E.g. clearing pending interrupts.287+288+289+3.6 Register IRQ handler290+~~~~~~~~~~~~~~~~~~~~~~~~291+While calling request_irq() is the the last step described here,292+this is often just another intermediate step to initialize a device.293+This step can often be deferred until the device is opened for use.294+295+All interrupt handlers for IRQ lines should be registered with IRQF_SHARED296+and use the devid to map IRQs to devices (remember that all PCI IRQ lines297+can be shared).298+299+request_irq() will associate an interrupt handler and device handle300+with an interrupt number. Historically interrupt numbers represent301+IRQ lines which run from the PCI device to the Interrupt controller.302+With MSI and MSI-X (more below) the interrupt number is a CPU "vector".303+304+request_irq() also enables the interrupt. Make sure the device is305+quiesced and does not have any interrupts pending before registering306+the interrupt handler.307+308+MSI and MSI-X are PCI capabilities. Both are "Message Signaled Interrupts"309+which deliver interrupts to the CPU via a DMA write to a Local APIC.310+The fundamental difference between MSI and MSI-X is how multiple311+"vectors" get allocated. MSI requires contiguous blocks of vectors312+while MSI-X can allocate several individual ones.313+314+MSI capability can be enabled by calling pci_enable_msi() or315+pci_enable_msix() before calling request_irq(). This causes316+the PCI support to program CPU vector data into the PCI device317+capability registers.318+319+If your PCI device supports both, try to enable MSI-X first.320+Only one can be enabled at a time. Many architectures, chip-sets,321+or BIOSes do NOT support MSI or MSI-X and the call to pci_enable_msi/msix322+will fail. This is important to note since many drivers have323+two (or more) interrupt handlers: one for MSI/MSI-X and another for IRQs.324+They choose which handler to register with request_irq() based on the325+return value from pci_enable_msi/msix().326+327+There are (at least) two really good reasons for using MSI:328+1) MSI is an exclusive interrupt vector by definition.329+ This means the interrupt handler doesn't have to verify330+ its device caused the interrupt.331+332+2) MSI avoids DMA/IRQ race conditions. DMA to host memory is guaranteed333+ to be visible to the host CPU(s) when the MSI is delivered. This334+ is important for both data coherency and avoiding stale control data.335+ This guarantee allows the driver to omit MMIO reads to flush336+ the DMA stream.337+338+See drivers/infiniband/hw/mthca/ or drivers/net/tg3.c for examples339+of MSI/MSI-X usage.340+341+342+343+4. PCI device shutdown344+~~~~~~~~~~~~~~~~~~~~~~~345+346+When a PCI device driver is being unloaded, most of the following347+steps need to be performed:348+349+ Disable the device from generating IRQs350+ Release the IRQ (free_irq())351+ Stop all DMA activity352+ Release DMA buffers (both streaming and consistent)353+ Unregister from other subsystems (e.g. scsi or netdev)354+ Disable device from responding to MMIO/IO Port addresses355+ Release MMIO/IO Port resource(s)356+357+358+4.1 Stop IRQs on the device359+~~~~~~~~~~~~~~~~~~~~~~~~~~~360+How to do this is chip/device specific. If it's not done, it opens361+the possibility of a "screaming interrupt" if (and only if)362+the IRQ is shared with another device.363+364+When the shared IRQ handler is "unhooked", the remaining devices365+using the same IRQ line will still need the IRQ enabled. Thus if the366+"unhooked" device asserts IRQ line, the system will respond assuming367+it was one of the remaining devices asserted the IRQ line. Since none368+of the other devices will handle the IRQ, the system will "hang" until369+it decides the IRQ isn't going to get handled and masks the IRQ (100,000370+iterations later). Once the shared IRQ is masked, the remaining devices371+will stop functioning properly. Not a nice situation.372+373+This is another reason to use MSI or MSI-X if it's available.374+MSI and MSI-X are defined to be exclusive interrupts and thus375+are not susceptible to the "screaming interrupt" problem.376+377+378+4.2 Release the IRQ379+~~~~~~~~~~~~~~~~~~~380+Once the device is quiesced (no more IRQs), one can call free_irq().381+This function will return control once any pending IRQs are handled,382+"unhook" the drivers IRQ handler from that IRQ, and finally release383+the IRQ if no one else is using it.384+385+386+4.3 Stop all DMA activity387+~~~~~~~~~~~~~~~~~~~~~~~~~388+It's extremely important to stop all DMA operations BEFORE attempting389+to deallocate DMA control data. Failure to do so can result in memory390+corruption, hangs, and on some chip-sets a hard crash.391+392+Stopping DMA after stopping the IRQs can avoid races where the393+IRQ handler might restart DMA engines.394+395+While this step sounds obvious and trivial, several "mature" drivers396+didn't get this step right in the past.397+398+399+4.4 Release DMA buffers400+~~~~~~~~~~~~~~~~~~~~~~~401+Once DMA is stopped, clean up streaming DMA first.402+I.e. unmap data buffers and return buffers to "upstream"403+owners if there is one.404+405+Then clean up "consistent" buffers which contain the control data.406+407+See Documentation/DMA-API.txt for details on unmapping interfaces.408+409+410+4.5 Unregister from other subsystems411+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~412+Most low level PCI device drivers support some other subsystem413+like USB, ALSA, SCSI, NetDev, Infiniband, etc. Make sure your414+driver isn't losing resources from that other subsystem.415+If this happens, typically the symptom is an Oops (panic) when416+the subsystem attempts to call into a driver that has been unloaded.417+418+419+4.6 Disable Device from responding to MMIO/IO Port addresses420+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~421+io_unmap() MMIO or IO Port resources and then call pci_disable_device().422+This is the symmetric opposite of pci_enable_device().423+Do not access device registers after calling pci_disable_device().424+425+426+4.7 Release MMIO/IO Port Resource(s)427+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~428+Call pci_release_region() to mark the MMIO or IO Port range as available.429+Failure to do so usually results in the inability to reload the driver.430+431+432+433+5. How to access PCI config space434~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~435+436+You can use pci_(read|write)_config_(byte|word|dword) to access the config437space of a device represented by struct pci_dev *. All these functions return 0438when successful or an error code (PCIBIOS_...) which can be translated to a text439string by pcibios_strerror. Most drivers expect that accesses to valid PCI440devices don't fail.441442+If you don't have a struct pci_dev available, you can call443pci_bus_(read|write)_config_(byte|word|dword) to access a given device444and function on that bus.445446+If you access fields in the standard portion of the config header, please447use symbolic names of locations and bits declared in <linux/pci.h>.448449+If you need to access Extended PCI Capability registers, just call450pci_find_capability() for the particular capability and it will find the451corresponding register block for you.452453000000000000000000000004544556. Other interesting functions456~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~457+458pci_find_slot() Find pci_dev corresponding to given bus and459 slot numbers.460pci_set_power_state() Set PCI Power Management state (0=D0 ... 3=D3)···247pci_clear_mwi() Disable Memory-Write-Invalidate transactions.248249250+2517. Miscellaneous hints252~~~~~~~~~~~~~~~~~~~~~~253+254+When displaying PCI device names to the user (for example when a driver wants255+to tell the user what card has it found), please use pci_name(pci_dev).256257Always refer to the PCI devices by a pointer to the pci_dev structure.258All PCI layer functions use this identification and it's the only···259special purposes -- on systems with multiple primary buses their semantics260can be pretty complex.261000262Don't try to turn on Fast Back to Back writes in your driver. All devices263on the bus need to be capable of doing it, so this is something which needs264to be handled by platform and generic code, not individual drivers.265266267+2688. Vendor and device identifications269~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~0270271+One is not not required to add new device ids to include/linux/pci_ids.h.272+Please add PCI_VENDOR_ID_xxx for vendors and a hex constant for device ids.273274+PCI_VENDOR_ID_xxx constants are re-used. The device ids are arbitrary275+hex numbers (vendor controlled) and normally used only in a single276+location, the pci_device_id table.277+278+Please DO submit new vendor/device ids to pciids.sourceforge.net project.279+280+2812829. Obsolete functions283~~~~~~~~~~~~~~~~~~~~~284+285There are several functions which you might come across when trying to286port an old driver to the new PCI interface. They are no longer present287in the kernel as they aren't compatible with hotplug or PCI domains or288having sane locking.289290+pci_find_device() Superseded by pci_get_device()291+pci_find_subsys() Superseded by pci_get_subsys()292+pci_find_slot() Superseded by pci_get_slot()293+294+295+The alternative is the traditional PCI device driver that walks PCI296+device lists. This is still possible but discouraged.297+298+299+300+10. pci_enable_device_bars() and Legacy I/O Port space301+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~302+303+Large servers may not be able to provide I/O port resources to all PCI304+devices. I/O Port space is only 64KB on Intel Architecture[1] and is305+likely also fragmented since the I/O base register of PCI-to-PCI306+bridge will usually be aligned to a 4KB boundary[2]. On such systems,307+pci_enable_device() and pci_request_region() will fail when308+attempting to enable I/O Port regions that don't have I/O Port309+resources assigned.310+311+Fortunately, many PCI devices which request I/O Port resources also312+provide access to the same registers via MMIO BARs. These devices can313+be handled without using I/O port space and the drivers typically314+offer a CONFIG_ option to only use MMIO regions315+(e.g. CONFIG_TULIP_MMIO). PCI devices typically provide I/O port316+interface for legacy OSes and will work when I/O port resources are not317+assigned. The "PCI Local Bus Specification Revision 3.0" discusses318+this on p.44, "IMPLEMENTATION NOTE".319+320+If your PCI device driver doesn't need I/O port resources assigned to321+I/O Port BARs, you should use pci_enable_device_bars() instead of322+pci_enable_device() in order not to enable I/O port regions for the323+corresponding devices. In addition, you should use324+pci_request_selected_regions() and pci_release_selected_regions()325+instead of pci_request_regions()/pci_release_regions() in order not to326+request/release I/O port regions for the corresponding devices.327+328+[1] Some systems support 64KB I/O port space per PCI segment.329+[2] Some PCI-to-PCI bridges support optional 1KB aligned I/O base.330+331+332+333+11. MMIO Space and "Write Posting"334+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~335+336+Converting a driver from using I/O Port space to using MMIO space337+often requires some additional changes. Specifically, "write posting"338+needs to be handled. Many drivers (e.g. tg3, acenic, sym53c8xx_2)339+already do this. I/O Port space guarantees write transactions reach the PCI340+device before the CPU can continue. Writes to MMIO space allow the CPU341+to continue before the transaction reaches the PCI device. HW weenies342+call this "Write Posting" because the write completion is "posted" to343+the CPU before the transaction has reached its destination.344+345+Thus, timing sensitive code should add readl() where the CPU is346+expected to wait before doing other work. The classic "bit banging"347+sequence works fine for I/O Port space:348+349+ for (i = 8; --i; val >>= 1) {350+ outb(val & 1, ioport_reg); /* write bit */351+ udelay(10);352+ }353+354+The same sequence for MMIO space should be:355+356+ for (i = 8; --i; val >>= 1) {357+ writeb(val & 1, mmio_reg); /* write bit */358+ readb(safe_mmio_reg); /* flush posted write */359+ udelay(10);360+ }361+362+It is important that "safe_mmio_reg" not have any side effects that363+interferes with the correct operation of the device.364+365+Another case to watch out for is when resetting a PCI device. Use PCI366+Configuration space reads to flush the writel(). This will gracefully367+handle the PCI master abort on all platforms if the PCI device is368+expected to not respond to a readl(). Most x86 platforms will allow369+MMIO reads to master abort (a.k.a. "Soft Fail") and return garbage370+(e.g. ~0). But many RISC platforms will crash (a.k.a."Hard Fail").371+
+1-1
Documentation/usb/CREDITS
···21 Bill Ryder <bryder@sgi.com>22 Thomas Sailer <sailer@ife.ee.ethz.ch>23 Gregory P. Smith <greg@electricrain.com>24- Linus Torvalds <torvalds@osdl.org>25 Roman Weissgaerber <weissg@vienna.at>26 <Kazuki.Yasumatsu@fujixerox.co.jp>27
···21 Bill Ryder <bryder@sgi.com>22 Thomas Sailer <sailer@ife.ee.ethz.ch>23 Gregory P. Smith <greg@electricrain.com>24+ Linus Torvalds <torvalds@linux-foundation.org>25 Roman Weissgaerber <weissg@vienna.at>26 <Kazuki.Yasumatsu@fujixerox.co.jp>27
+3-3
MAINTAINERS
···12541255ETHERNET BRIDGE1256P: Stephen Hemminger1257-M: shemminger@osdl.org1258L: bridge@osdl.org1259W: http://bridge.sourceforge.net/1260S: Maintained···22772278NETEM NETWORK EMULATOR2279P: Stephen Hemminger2280-M: shemminger@osdl.org2281L: netem@osdl.org2282S: Maintained2283···30813082SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS3083P: Stephen Hemminger3084-M: shemminger@osdl.org3085L: netdev@vger.kernel.org3086S: Maintained3087
···12541255ETHERNET BRIDGE1256P: Stephen Hemminger1257+M: shemminger@linux-foundation.org1258L: bridge@osdl.org1259W: http://bridge.sourceforge.net/1260S: Maintained···22772278NETEM NETWORK EMULATOR2279P: Stephen Hemminger2280+M: shemminger@linux-foundation.org2281L: netem@osdl.org2282S: Maintained2283···30813082SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS3083P: Stephen Hemminger3084+M: shemminger@linux-foundation.org3085L: netdev@vger.kernel.org3086S: Maintained3087
+2-2
README
···278 the file MAINTAINERS to see if there is a particular person associated279 with the part of the kernel that you are having trouble with. If there280 isn't anyone listed there, then the second best thing is to mail281- them to me (torvalds@osdl.org), and possibly to any other relevant282- mailing-list or to the newsgroup.283284 - In all bug-reports, *please* tell what kernel you are talking about,285 how to duplicate the problem, and what your setup is (use your common
···278 the file MAINTAINERS to see if there is a particular person associated279 with the part of the kernel that you are having trouble with. If there280 isn't anyone listed there, then the second best thing is to mail281+ them to me (torvalds@linux-foundation.org), and possibly to any other282+ relevant mailing-list or to the newsgroup.283284 - In all bug-reports, *please* tell what kernel you are talking about,285 how to duplicate the problem, and what your setup is (use your common
+9-4
arch/i386/kernel/cpu/common.c
···710 return 1;711}712713-/* Common CPU init for both boot and secondary CPUs */714-static void __cpuinit _cpu_init(int cpu, struct task_struct *curr)715{716- struct tss_struct * t = &per_cpu(init_tss, cpu);717- struct thread_struct *thread = &curr->thread;718 struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);719720 /* Reinit these anyway, even if they've already been done (on···719 the real ones). */720 load_gdt(cpu_gdt_descr);721 set_kernel_gs();0000000722723 if (cpu_test_and_set(cpu, cpu_initialized)) {724 printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);···811 local_irq_enable();812 }8130814 _cpu_init(cpu, curr);815}816
···710 return 1;711}712713+void __cpuinit cpu_set_gdt(int cpu)0714{00715 struct Xgt_desc_struct *cpu_gdt_descr = &per_cpu(cpu_gdt_descr, cpu);716717 /* Reinit these anyway, even if they've already been done (on···722 the real ones). */723 load_gdt(cpu_gdt_descr);724 set_kernel_gs();725+}726+727+/* Common CPU init for both boot and secondary CPUs */728+static void __cpuinit _cpu_init(int cpu, struct task_struct *curr)729+{730+ struct tss_struct * t = &per_cpu(init_tss, cpu);731+ struct thread_struct *thread = &curr->thread;732733 if (cpu_test_and_set(cpu, cpu_initialized)) {734 printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);···807 local_irq_enable();808 }809810+ cpu_set_gdt(cpu);811 _cpu_init(cpu, curr);812}813
+1-7
arch/i386/kernel/nmi.c
···310311 if ((nmi >= NMI_INVALID) || (nmi < NMI_NONE))312 return 0;313- /*314- * If any other x86 CPU has a local APIC, then315- * please test the NMI stuff there and send me the316- * missing bits. Right now Intel P6/P4 and AMD K7 only.317- */318- if ((nmi == NMI_LOCAL_APIC) && (nmi_known_cpu() == 0))319- return 0; /* no lapic support */320 nmi_watchdog = nmi;321 return 1;322}
···566 .irq_enable_sysexit = native_irq_enable_sysexit,567 .iret = native_iret,568};569+570+/*571+ * NOTE: CONFIG_PARAVIRT is experimental and the paravirt_ops572+ * semantics are subject to change. Hence we only do this573+ * internal-only export of this, until it gets sorted out and574+ * all lowlevel CPU ops used by modules are separately exported.575+ */576+EXPORT_SYMBOL_GPL(paravirt_ops);
+6-3
arch/i386/kernel/smpboot.c
···596void __devinit initialize_secondary(void)597{598 /*000000599 * We don't actually need to load the full TSS,600 * basically just the stack pointer and the eip.601 */···977 printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip);978 /* Stack for startup_32 can be just as for start_secondary onwards */979 stack_start.esp = (void *) idle->thread.esp;980-981- start_pda = cpu_pda(cpu);982- cpu_gdt_descr = per_cpu(cpu_gdt_descr, cpu);983984 irq_ctx_init(cpu);985
···596void __devinit initialize_secondary(void)597{598 /*599+ * switch to the per CPU GDT we already set up600+ * in do_boot_cpu()601+ */602+ cpu_set_gdt(current_thread_info()->cpu);603+604+ /*605 * We don't actually need to load the full TSS,606 * basically just the stack pointer and the eip.607 */···971 printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip);972 /* Stack for startup_32 can be just as for start_secondary onwards */973 stack_start.esp = (void *) idle->thread.esp;000974975 irq_ctx_init(cpu);976
+6
arch/i386/mach-voyager/voyager_smp.c
···773#endif774775 /*000000776 * We don't actually need to load the full TSS,777 * basically just the stack pointer and the eip.778 */
···773#endif774775 /*776+ * switch to the per CPU GDT we already set up777+ * in do_boot_cpu()778+ */779+ cpu_set_gdt(current_thread_info()->cpu);780+781+ /*782 * We don't actually need to load the full TSS,783 * basically just the stack pointer and the eip.784 */
+14
arch/mips/Kconfig
···1568 depends on MIPS_MT1569 default y1570000000000000001571config MIPS_VPE_LOADER_TOM1572 bool "Load VPE program into memory hidden from linux"1573 depends on MIPS_VPE_LOADER
···1568 depends on MIPS_MT1569 default y15701571+config MIPS_MT_SMTC_INSTANT_REPLAY1572+ bool "Low-latency Dispatch of Deferred SMTC IPIs"1573+ depends on MIPS_MT_SMTC1574+ default y1575+ help1576+ SMTC pseudo-interrupts between TCs are deferred and queued1577+ if the target TC is interrupt-inhibited (IXMT). In the first1578+ SMTC prototypes, these queued IPIs were serviced on return1579+ to user mode, or on entry into the kernel idle loop. The1580+ INSTANT_REPLAY option dispatches them as part of local_irq_restore()1581+ processing, which adds runtime overhead (hence the option to turn1582+ it off), but ensures that IPIs are handled promptly even under1583+ heavy I/O interrupt load.1584+1585config MIPS_VPE_LOADER_TOM1586 bool "Load VPE program into memory hidden from linux"1587 depends on MIPS_VPE_LOADER
+34-22
arch/mips/kernel/smtc.c
···1017 * SMTC-specific hacks invoked from elsewhere in the kernel.1018 */10190000000000000000000000000001020void smtc_idle_loop_hook(void)1021{1022#ifdef SMTC_IDLE_HOOK_DEBUG···1140 if (pdb_msg != &id_ho_db_msg[0])1141 printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg);1142#endif /* SMTC_IDLE_HOOK_DEBUG */1143- /*1144- * To the extent that we've ever turned interrupts off,1145- * we may have accumulated deferred IPIs. This is subtle.1146- * If we use the smtc_ipi_qdepth() macro, we'll get an1147- * exact number - but we'll also disable interrupts1148- * and create a window of failure where a new IPI gets1149- * queued after we test the depth but before we re-enable1150- * interrupts. So long as IXMT never gets set, however,1151- * we should be OK: If we pick up something and dispatch1152- * it here, that's great. If we see nothing, but concurrent1153- * with this operation, another TC sends us an IPI, IXMT1154- * is clear, and we'll handle it as a real pseudo-interrupt1155- * and not a pseudo-pseudo interrupt.1156- */1157- if (IPIQ[smp_processor_id()].depth > 0) {1158- struct smtc_ipi *pipi;1159- extern void self_ipi(struct smtc_ipi *);11601161- if ((pipi = smtc_ipi_dq(&IPIQ[smp_processor_id()])) != NULL) {1162- self_ipi(pipi);1163- smtc_cpu_stats[smp_processor_id()].selfipis++;1164- }1165- }001166}11671168void smtc_soft_dump(void)
···1017 * SMTC-specific hacks invoked from elsewhere in the kernel.1018 */10191020+void smtc_ipi_replay(void)1021+{1022+ /*1023+ * To the extent that we've ever turned interrupts off,1024+ * we may have accumulated deferred IPIs. This is subtle.1025+ * If we use the smtc_ipi_qdepth() macro, we'll get an1026+ * exact number - but we'll also disable interrupts1027+ * and create a window of failure where a new IPI gets1028+ * queued after we test the depth but before we re-enable1029+ * interrupts. So long as IXMT never gets set, however,1030+ * we should be OK: If we pick up something and dispatch1031+ * it here, that's great. If we see nothing, but concurrent1032+ * with this operation, another TC sends us an IPI, IXMT1033+ * is clear, and we'll handle it as a real pseudo-interrupt1034+ * and not a pseudo-pseudo interrupt.1035+ */1036+ if (IPIQ[smp_processor_id()].depth > 0) {1037+ struct smtc_ipi *pipi;1038+ extern void self_ipi(struct smtc_ipi *);1039+1040+ while ((pipi = smtc_ipi_dq(&IPIQ[smp_processor_id()]))) {1041+ self_ipi(pipi);1042+ smtc_cpu_stats[smp_processor_id()].selfipis++;1043+ }1044+ }1045+}1046+1047void smtc_idle_loop_hook(void)1048{1049#ifdef SMTC_IDLE_HOOK_DEBUG···1113 if (pdb_msg != &id_ho_db_msg[0])1114 printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg);1115#endif /* SMTC_IDLE_HOOK_DEBUG */0000000000000000011161117+ /*1118+ * Replay any accumulated deferred IPIs. If "Instant Replay"1119+ * is in use, there should never be any.1120+ */1121+#ifndef CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY1122+ smtc_ipi_replay();1123+#endif /* CONFIG_MIPS_MT_SMTC_INSTANT_REPLAY */1124}11251126void smtc_soft_dump(void)
+9-3
arch/mips/vr41xx/common/irq.c
···1/*2 * Interrupt handing routines for NEC VR4100 series.3 *4- * Copyright (C) 2005 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>5 *6 * This program is free software; you can redistribute it and/or modify7 * it under the terms of the GNU General Public License as published by···73 if (cascade->get_irq != NULL) {74 unsigned int source_irq = irq;75 desc = irq_desc + source_irq;76- desc->chip->ack(source_irq);0000077 irq = cascade->get_irq(irq);78 if (irq < 0)79 atomic_inc(&irq_err_count);80 else81 irq_dispatch(irq);82- desc->chip->end(source_irq);083 } else84 do_IRQ(irq);85}
···1/*2 * Interrupt handing routines for NEC VR4100 series.3 *4+ * Copyright (C) 2005-2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp>5 *6 * This program is free software; you can redistribute it and/or modify7 * it under the terms of the GNU General Public License as published by···73 if (cascade->get_irq != NULL) {74 unsigned int source_irq = irq;75 desc = irq_desc + source_irq;76+ if (desc->chip->mask_ack)77+ desc->chip->mask_ack(source_irq);78+ else {79+ desc->chip->mask(source_irq);80+ desc->chip->ack(source_irq);81+ }82 irq = cascade->get_irq(irq);83 if (irq < 0)84 atomic_inc(&irq_err_count);85 else86 irq_dispatch(irq);87+ if (!(desc->status & IRQ_DISABLED) && desc->chip->unmask)88+ desc->chip->unmask(source_irq);89 } else90 do_IRQ(irq);91}
···590 */591 rq->cmd_flags |= REQ_SOFTBARRIER;592000000593 if (q->ordseq == 0) {594 list_add(&rq->queuelist, &q->queue_head);595 break;···610 }611612 list_add_tail(&rq->queuelist, pos);613- /*614- * most requeues happen because of a busy condition, don't615- * force unplug of the queue for that case.616- */617- unplug_it = 0;618 break;619620 default:
···590 */591 rq->cmd_flags |= REQ_SOFTBARRIER;592593+ /*594+ * Most requeues happen because of a busy condition,595+ * don't force unplug of the queue for that case.596+ */597+ unplug_it = 0;598+599 if (q->ordseq == 0) {600 list_add(&rq->queuelist, &q->queue_head);601 break;···604 }605606 list_add_tail(&rq->queuelist, pos);00000607 break;608609 default:
···700 goto done;701 }702 if (buf->state == STATE_QUEUED ||0703 buf->state == STATE_ACTIVE) {704 dprintk(1,"qbuf: buffer is already queued or active.\n");705 goto done;
···700 goto done;701 }702 if (buf->state == STATE_QUEUED ||703+ buf->state == STATE_PREPARED ||704 buf->state == STATE_ACTIVE) {705 dprintk(1,"qbuf: buffer is already queued or active.\n");706 goto done;
+13-2
drivers/mtd/Kconfig
···164 memory chips, and also use ioctl() to obtain information about165 the device, or to erase parts of it.16600000167config MTD_BLOCK168 tristate "Caching block device access to MTD devices"169 depends on MTD && BLOCK0170 ---help---171 Although most flash chips have an erase size too large to be useful172 as block devices, it is possible to use MTD devices which are based···195config MTD_BLOCK_RO196 tristate "Readonly block device access to MTD devices"197 depends on MTD_BLOCK!=y && MTD && BLOCK0198 help199 This allows you to mount read-only file systems (such as cramfs)200 from an MTD device, without the overhead (and danger) of the caching···207config FTL208 tristate "FTL (Flash Translation Layer) support"209 depends on MTD && BLOCK0210 ---help---211 This provides support for the original Flash Translation Layer which212 is part of the PCMCIA specification. It uses a kind of pseudo-···224config NFTL225 tristate "NFTL (NAND Flash Translation Layer) support"226 depends on MTD && BLOCK0227 ---help---228 This provides support for the NAND Flash Translation Layer which is229 used on M-Systems' DiskOnChip devices. It uses a kind of pseudo-···248config INFTL249 tristate "INFTL (Inverse NAND Flash Translation Layer) support"250 depends on MTD && BLOCK0251 ---help---252 This provides support for the Inverse NAND Flash Translation253 Layer which is used on M-Systems' newer DiskOnChip devices. It···266config RFD_FTL267 tristate "Resident Flash Disk (Flash Translation Layer) support"268 depends on MTD && BLOCK0269 ---help---270 This provides support for the flash translation layer known271 as the Resident Flash Disk (RFD), as used by the Embedded BIOS···276277config SSFDC278 tristate "NAND SSFDC (SmartMedia) read only translation layer"279- depends on MTD280- default n281 help282 This enables read only access to SmartMedia formatted NAND283 flash. You can mount it with FAT file system.
···164 memory chips, and also use ioctl() to obtain information about165 the device, or to erase parts of it.166167+config MTD_BLKDEVS168+ tristate "Common interface to block layer for MTD 'translation layers'"169+ depends on MTD && BLOCK170+ default n171+172config MTD_BLOCK173 tristate "Caching block device access to MTD devices"174 depends on MTD && BLOCK175+ select MTD_BLKDEVS176 ---help---177 Although most flash chips have an erase size too large to be useful178 as block devices, it is possible to use MTD devices which are based···189config MTD_BLOCK_RO190 tristate "Readonly block device access to MTD devices"191 depends on MTD_BLOCK!=y && MTD && BLOCK192+ select MTD_BLKDEVS193 help194 This allows you to mount read-only file systems (such as cramfs)195 from an MTD device, without the overhead (and danger) of the caching···200config FTL201 tristate "FTL (Flash Translation Layer) support"202 depends on MTD && BLOCK203+ select MTD_BLKDEVS204 ---help---205 This provides support for the original Flash Translation Layer which206 is part of the PCMCIA specification. It uses a kind of pseudo-···216config NFTL217 tristate "NFTL (NAND Flash Translation Layer) support"218 depends on MTD && BLOCK219+ select MTD_BLKDEVS220 ---help---221 This provides support for the NAND Flash Translation Layer which is222 used on M-Systems' DiskOnChip devices. It uses a kind of pseudo-···239config INFTL240 tristate "INFTL (Inverse NAND Flash Translation Layer) support"241 depends on MTD && BLOCK242+ select MTD_BLKDEVS243 ---help---244 This provides support for the Inverse NAND Flash Translation245 Layer which is used on M-Systems' newer DiskOnChip devices. It···256config RFD_FTL257 tristate "Resident Flash Disk (Flash Translation Layer) support"258 depends on MTD && BLOCK259+ select MTD_BLKDEVS260 ---help---261 This provides support for the flash translation layer known262 as the Resident Flash Disk (RFD), as used by the Embedded BIOS···265266config SSFDC267 tristate "NAND SSFDC (SmartMedia) read only translation layer"268+ depends on MTD && BLOCK269+ select MTD_BLKDEVS270 help271 This enables read only access to SmartMedia formatted NAND272 flash. You can mount it with FAT file system.
···207 if (!sz)208 return ret;209210- parts = kmalloc(sz, GFP_KERNEL);211 if (!parts)212 return -ENOMEM;213214- memset(parts, 0, sz);215 str = (char *)(parts + idx);216217 /*
···207 if (!sz)208 return ret;209210+ parts = kzalloc(sz, GFP_KERNEL);211 if (!parts)212 return -ENOMEM;2130214 str = (char *)(parts + idx);215216 /*
+1-2
drivers/mtd/chips/amd_flash.c
···643 int reg_idx;644 int offset;645646- mtd = (struct mtd_info*)kmalloc(sizeof(*mtd), GFP_KERNEL);647 if (!mtd) {648 printk(KERN_WARNING649 "%s: kmalloc failed for info structure\n", map->name);650 return NULL;651 }652- memset(mtd, 0, sizeof(*mtd));653 mtd->priv = map;654655 memset(&temp, 0, sizeof(temp));
···643 int reg_idx;644 int offset;645646+ mtd = kzalloc(sizeof(*mtd), GFP_KERNEL);647 if (!mtd) {648 printk(KERN_WARNING649 "%s: kmalloc failed for info structure\n", map->name);650 return NULL;651 }0652 mtd->priv = map;653654 memset(&temp, 0, sizeof(temp));
+3-2
drivers/mtd/chips/cfi_cmdset_0001.c
···337 struct mtd_info *mtd;338 int i;339340- mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);341 if (!mtd) {342 printk(KERN_ERR "Failed to allocate memory for MTD device\n");343 return NULL;344 }345- memset(mtd, 0, sizeof(*mtd));346 mtd->priv = map;347 mtd->type = MTD_NORFLASH;348···2223 case FL_CFI_QUERY:2224 case FL_JEDEC_QUERY:2225 if (chip->oldstate == FL_READY) {002226 chip->oldstate = chip->state;2227 chip->state = FL_PM_SUSPENDED;2228 /* No need to wake_up() on this state change -
···337 struct mtd_info *mtd;338 int i;339340+ mtd = kzalloc(sizeof(*mtd), GFP_KERNEL);341 if (!mtd) {342 printk(KERN_ERR "Failed to allocate memory for MTD device\n");343 return NULL;344 }0345 mtd->priv = map;346 mtd->type = MTD_NORFLASH;347···2224 case FL_CFI_QUERY:2225 case FL_JEDEC_QUERY:2226 if (chip->oldstate == FL_READY) {2227+ /* place the chip in a known state before suspend */2228+ map_write(map, CMD(0xFF), cfi->chips[i].start);2229 chip->oldstate = chip->state;2230 chip->state = FL_PM_SUSPENDED;2231 /* No need to wake_up() on this state change -
+7-4
drivers/mtd/chips/cfi_cmdset_0002.c
···48#define MANUFACTURER_ATMEL 0x001F49#define MANUFACTURER_SST 0x00BF50#define SST49LF004B 0x0060051#define SST49LF008A 0x005a52#define AT49BV6416 0x00d653···234};235static struct cfi_fixup jedec_fixup_table[] = {236 { MANUFACTURER_SST, SST49LF004B, fixup_use_fwh_lock, NULL, },0237 { MANUFACTURER_SST, SST49LF008A, fixup_use_fwh_lock, NULL, },238 { 0, 0, NULL, NULL }239};···257 struct mtd_info *mtd;258 int i;259260- mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);261 if (!mtd) {262 printk(KERN_WARNING "Failed to allocate memory for MTD device\n");263 return NULL;264 }265- memset(mtd, 0, sizeof(*mtd));266 mtd->priv = map;267 mtd->type = MTD_NORFLASH;268···520 if (mode == FL_WRITING) /* FIXME: Erase-suspend-program appears broken. */521 goto sleep;522523- if (!(mode == FL_READY || mode == FL_POINT0524 || !cfip525 || (mode == FL_WRITING && (cfip->EraseSuspend & 0x2))526- || (mode == FL_WRITING && (cfip->EraseSuspend & 0x1))))0527 goto sleep;528529 /* We could check to see if we're trying to access the sector
···48#define MANUFACTURER_ATMEL 0x001F49#define MANUFACTURER_SST 0x00BF50#define SST49LF004B 0x006051+#define SST49LF040B 0x005052#define SST49LF008A 0x005a53#define AT49BV6416 0x00d654···233};234static struct cfi_fixup jedec_fixup_table[] = {235 { MANUFACTURER_SST, SST49LF004B, fixup_use_fwh_lock, NULL, },236+ { MANUFACTURER_SST, SST49LF040B, fixup_use_fwh_lock, NULL, },237 { MANUFACTURER_SST, SST49LF008A, fixup_use_fwh_lock, NULL, },238 { 0, 0, NULL, NULL }239};···255 struct mtd_info *mtd;256 int i;257258+ mtd = kzalloc(sizeof(*mtd), GFP_KERNEL);259 if (!mtd) {260 printk(KERN_WARNING "Failed to allocate memory for MTD device\n");261 return NULL;262 }0263 mtd->priv = map;264 mtd->type = MTD_NORFLASH;265···519 if (mode == FL_WRITING) /* FIXME: Erase-suspend-program appears broken. */520 goto sleep;521522+ if (!( mode == FL_READY523+ || mode == FL_POINT524 || !cfip525 || (mode == FL_WRITING && (cfip->EraseSuspend & 0x2))526+ || (mode == FL_WRITING && (cfip->EraseSuspend & 0x1)527+ )))528 goto sleep;529530 /* We could check to see if we're trying to access the sector
···154#define SST39SF010A 0x00B5155#define SST39SF020A 0x00B6156#define SST49LF004B 0x00600157#define SST49LF008A 0x005a158#define SST49LF030A 0x001C159#define SST49LF040A 0x0051···1402 }1403 }, {1404 .mfr_id = MANUFACTURER_SST,000000000000001405 .dev_id = SST49LF004B,1406 .name = "SST 49LF004B",1407 .uaddr = {···188918901891/*1892- * There is a BIG problem properly ID'ing the JEDEC devic and guaranteeing1893 * the mapped address, unlock addresses, and proper chip ID. This function1894 * attempts to minimize errors. It is doubtfull that this probe will ever1895 * be perfect - consequently there should be some module parameters that
···154#define SST39SF010A 0x00B5155#define SST39SF020A 0x00B6156#define SST49LF004B 0x0060157+#define SST49LF040B 0x0050158#define SST49LF008A 0x005a159#define SST49LF030A 0x001C160#define SST49LF040A 0x0051···1401 }1402 }, {1403 .mfr_id = MANUFACTURER_SST,1404+ .dev_id = SST49LF040B,1405+ .name = "SST 49LF040B",1406+ .uaddr = {1407+ [0] = MTD_UADDR_0x5555_0x2AAA /* x8 */1408+ },1409+ .DevSize = SIZE_512KiB,1410+ .CmdSet = P_ID_AMD_STD,1411+ .NumEraseRegions= 1,1412+ .regions = {1413+ ERASEINFO(0x01000,128),1414+ }1415+ }, {1416+1417+ .mfr_id = MANUFACTURER_SST,1418 .dev_id = SST49LF004B,1419 .name = "SST 49LF004B",1420 .uaddr = {···187418751876/*1877+ * There is a BIG problem properly ID'ing the JEDEC device and guaranteeing1878 * the mapped address, unlock addresses, and proper chip ID. This function1879 * attempts to minimize errors. It is doubtfull that this probe will ever1880 * be perfect - consequently there should be some module parameters that
···55#endif56 /* OK. It seems to be RAM. */5758- mtd = kmalloc(sizeof(*mtd), GFP_KERNEL);59 if (!mtd)60 return NULL;61-62- memset(mtd, 0, sizeof(*mtd));6364 map->fldrv = &mapram_chipdrv;65 mtd->priv = map;
···55#endif56 /* OK. It seems to be RAM. */5758+ mtd = kzalloc(sizeof(*mtd), GFP_KERNEL);59 if (!mtd)60 return NULL;006162 map->fldrv = &mapram_chipdrv;63 mtd->priv = map;
···163 *num_parts = this_part + 1;164 alloc_size = *num_parts * sizeof(struct mtd_partition) +165 extra_mem_size;166- parts = kmalloc(alloc_size, GFP_KERNEL);167 if (!parts)168 {169 printk(KERN_ERR ERRP "out of memory\n");170 return NULL;171 }172- memset(parts, 0, alloc_size);173 extra_mem = (unsigned char *)(parts + *num_parts);174 }175 /* enter this partition (offset will be calculated later if it is zero at this point) */···345 *346 * This function needs to be visible for bootloaders.347 */348-int mtdpart_setup(char *s)349{350 cmdline = s;351 return 1;
···163 *num_parts = this_part + 1;164 alloc_size = *num_parts * sizeof(struct mtd_partition) +165 extra_mem_size;166+ parts = kzalloc(alloc_size, GFP_KERNEL);167 if (!parts)168 {169 printk(KERN_ERR ERRP "out of memory\n");170 return NULL;171 }0172 extra_mem = (unsigned char *)(parts + *num_parts);173 }174 /* enter this partition (offset will be calculated later if it is zero at this point) */···346 *347 * This function needs to be visible for bootloaders.348 */349+static int mtdpart_setup(char *s)350{351 cmdline = s;352 return 1;
+1-2
drivers/mtd/devices/block2mtd.c
···295 if (!devname)296 return NULL;297298- dev = kmalloc(sizeof(struct block2mtd_dev), GFP_KERNEL);299 if (!dev)300 return NULL;301- memset(dev, 0, sizeof(*dev));302303 /* Get a handle on the device */304 bdev = open_bdev_excl(devname, O_RDWR, NULL);
···295 if (!devname)296 return NULL;297298+ dev = kzalloc(sizeof(struct block2mtd_dev), GFP_KERNEL);299 if (!dev)300 return NULL;0301302 /* Get a handle on the device */303 bdev = open_bdev_excl(devname, O_RDWR, NULL);
···126 struct phram_mtd_list *new;127 int ret = -ENOMEM;128129- new = kmalloc(sizeof(*new), GFP_KERNEL);130 if (!new)131 goto out0;132-133- memset(new, 0, sizeof(*new));134135 ret = -EIO;136 new->mtd.priv = ioremap(start, len);
···126 struct phram_mtd_list *new;127 int ret = -ENOMEM;128129+ new = kzalloc(sizeof(*new), GFP_KERNEL);130 if (!new)131 goto out0;00132133 ret = -EIO;134 new->mtd.priv = ioremap(start, len);
···60 Ignore this option if you use run-time physmap configuration61 (i.e., run-time calling physmap_configure()).6200000000063config MTD_SUN_UFLASH64 tristate "Sun Microsystems userflash support"65 depends on SPARC && MTD_CFI···189 depends on X86 && MTD_JEDECPROBE190 help191 Support for treating the BIOS flash chip on ICHX motherboards000000000000000000192 as an MTD device - with this you can reprogram your BIOS.193194 BE VERY CAREFUL.···381 This enables access routines for the flash chips on the382 TQ Components TQM834x boards. If you have one of these boards383 and would like to use the flash chips on it, say 'Y'.384-385-config MTD_CSTM_MIPS_IXX386- tristate "Flash chip mapping on ITE QED-4N-S01B, Globespan IVR or custom board"387- depends on MIPS && MTD_CFI && MTD_JEDECPROBE && MTD_PARTITIONS388- help389- This provides a mapping driver for the Integrated Technology390- Express, Inc (ITE) QED-4N-S01B eval board and the Globespan IVR391- Reference Board. It provides the necessary addressing, length,392- buswidth, vpp code and addition setup of the flash device for393- these boards. In addition, this mapping driver can be used for394- other boards via setting of the CONFIG_MTD_CSTM_MIPS_IXX_START/395- LEN/BUSWIDTH parameters. This mapping will provide one mtd device396- using one partition. The start address can be offset from the397- beginning of flash and the len can be less than the total flash398- device size to allow a window into the flash. Both CFI and JEDEC399- probes are called.400-401-config MTD_CSTM_MIPS_IXX_START402- hex "Physical start address of flash mapping"403- depends on MTD_CSTM_MIPS_IXX404- default "0x8000000"405- help406- This is the physical memory location that the MTD driver will407- use for the flash chips on your particular target board.408- Refer to the memory map which should hopefully be in the409- documentation for your board.410-411-config MTD_CSTM_MIPS_IXX_LEN412- hex "Physical length of flash mapping"413- depends on MTD_CSTM_MIPS_IXX414- default "0x4000000"415- help416- This is the total length that the MTD driver will use for the417- flash chips on your particular board. Refer to the memory418- map which should hopefully be in the documentation for your419- board.420-421-config MTD_CSTM_MIPS_IXX_BUSWIDTH422- int "Bus width in octets"423- depends on MTD_CSTM_MIPS_IXX424- default "2"425- help426- This is the total bus width of the mapping of the flash chips427- on your particular board.428429config MTD_OCELOT430 tristate "Momenco Ocelot boot flash device"
···60 Ignore this option if you use run-time physmap configuration61 (i.e., run-time calling physmap_configure()).6263+config MTD_PHYSMAP_OF64+ tristate "Flash device in physical memory map based on OF descirption"65+ depends on PPC_OF && (MTD_CFI || MTD_JEDECPROBE || MTD_ROM)66+ help67+ This provides a 'mapping' driver which allows the NOR Flash and68+ ROM driver code to communicate with chips which are mapped69+ physically into the CPU's memory. The mapping description here is70+ taken from OF device tree.71+72config MTD_SUN_UFLASH73 tristate "Sun Microsystems userflash support"74 depends on SPARC && MTD_CFI···180 depends on X86 && MTD_JEDECPROBE181 help182 Support for treating the BIOS flash chip on ICHX motherboards183+ as an MTD device - with this you can reprogram your BIOS.184+185+ BE VERY CAREFUL.186+187+config MTD_ESB2ROM188+ tristate "BIOS flash chip on Intel ESB Controller Hub 2"189+ depends on X86 && MTD_JEDECPROBE && PCI190+ help191+ Support for treating the BIOS flash chip on ESB2 motherboards192+ as an MTD device - with this you can reprogram your BIOS.193+194+ BE VERY CAREFUL.195+196+config MTD_CK804XROM197+ tristate "BIOS flash chip on Nvidia CK804"198+ depends on X86 && MTD_JEDECPROBE199+ help200+ Support for treating the BIOS flash chip on nvidia motherboards201 as an MTD device - with this you can reprogram your BIOS.202203 BE VERY CAREFUL.···354 This enables access routines for the flash chips on the355 TQ Components TQM834x boards. If you have one of these boards356 and would like to use the flash chips on it, say 'Y'.00000000000000000000000000000000000000000000357358config MTD_OCELOT359 tristate "Momenco Ocelot boot flash device"
···78#include <linux/module.h>9#include <linux/types.h>010#include <linux/kernel.h>11#include <linux/init.h>12#include <asm/io.h>···44 struct resource rsrc;45 char map_name[sizeof(MOD_NAME) + 2 + ADDRESS_NAME_LEN];46};000000000000000004748static struct amd76xrom_window amd76xrom_window = {49 .maps = LIST_HEAD_INIT(amd76xrom_window.maps),···113 /* Remember the pci dev I find the window in - already have a ref */114 window->pdev = pdev;1150000000000116 /* Assume the rom window is properly setup, and find it's size */117 pci_read_config_byte(pdev, 0x43, &byte);118 if ((byte & ((1<<7)|(1<<6))) == ((1<<7)|(1<<6))) {···157 (unsigned long long)window->rsrc.end);158 }159160-#if 0161-162- /* Enable the selected rom window */163- pci_read_config_byte(pdev, 0x43, &byte);164- pci_write_config_byte(pdev, 0x43, byte | rwindow->segen_bits);165-#endif166167 /* Enable writes through the rom window */168 pci_read_config_byte(pdev, 0x40, &byte);
···78#include <linux/module.h>9#include <linux/types.h>10+#include <linux/version.h>11#include <linux/kernel.h>12#include <linux/init.h>13#include <asm/io.h>···43 struct resource rsrc;44 char map_name[sizeof(MOD_NAME) + 2 + ADDRESS_NAME_LEN];45};46+47+/* The 2 bits controlling the window size are often set to allow reading48+ * the BIOS, but too small to allow writing, since the lock registers are49+ * 4MiB lower in the address space than the data.50+ *51+ * This is intended to prevent flashing the bios, perhaps accidentally.52+ *53+ * This parameter allows the normal driver to over-ride the BIOS settings.54+ *55+ * The bits are 6 and 7. If both bits are set, it is a 5MiB window.56+ * If only the 7 Bit is set, it is a 4MiB window. Otherwise, a57+ * 64KiB window.58+ *59+ */60+static uint win_size_bits;61+module_param(win_size_bits, uint, 0);62+MODULE_PARM_DESC(win_size_bits, "ROM window size bits override for 0x43 byte, normally set by BIOS.");6364static struct amd76xrom_window amd76xrom_window = {65 .maps = LIST_HEAD_INIT(amd76xrom_window.maps),···95 /* Remember the pci dev I find the window in - already have a ref */96 window->pdev = pdev;9798+ /* Enable the selected rom window. This is often incorrectly99+ * set up by the BIOS, and the 4MiB offset for the lock registers100+ * requires the full 5MiB of window space.101+ *102+ * This 'write, then read' approach leaves the bits for103+ * other uses of the hardware info.104+ */105+ pci_read_config_byte(pdev, 0x43, &byte);106+ pci_write_config_byte(pdev, 0x43, byte | win_size_bits );107+108 /* Assume the rom window is properly setup, and find it's size */109 pci_read_config_byte(pdev, 0x43, &byte);110 if ((byte & ((1<<7)|(1<<6))) == ((1<<7)|(1<<6))) {···129 (unsigned long long)window->rsrc.end);130 }131000000132133 /* Enable writes through the rom window */134 pci_read_config_byte(pdev, 0x40, &byte);
···122 /*123 * Allocate the map_info structs in one go.124 */125- maps = kmalloc(sizeof(struct map_info) * nr, GFP_KERNEL);126 if (!maps)127 return -ENOMEM;128- memset(maps, 0, sizeof(struct map_info) * nr);129 /*130 * Claim and then map the memory regions.131 */
···122 /*123 * Allocate the map_info structs in one go.124 */125+ maps = kzalloc(sizeof(struct map_info) * nr, GFP_KERNEL);126 if (!maps)127 return -ENOMEM;0128 /*129 * Claim and then map the memory regions.130 */
···1+/*2+ * ck804xrom.c3+ *4+ * Normal mappings of chips in physical memory5+ *6+ * Dave Olsen <dolsen@lnxi.com>7+ * Ryan Jackson <rjackson@lnxi.com>8+ */9+10+#include <linux/module.h>11+#include <linux/types.h>12+#include <linux/version.h>13+#include <linux/kernel.h>14+#include <linux/init.h>15+#include <asm/io.h>16+#include <linux/mtd/mtd.h>17+#include <linux/mtd/map.h>18+#include <linux/mtd/cfi.h>19+#include <linux/mtd/flashchip.h>20+#include <linux/pci.h>21+#include <linux/pci_ids.h>22+#include <linux/list.h>23+24+25+#define MOD_NAME KBUILD_BASENAME26+27+#define ADDRESS_NAME_LEN 1828+29+#define ROM_PROBE_STEP_SIZE (64*1024)30+31+struct ck804xrom_window {32+ void __iomem *virt;33+ unsigned long phys;34+ unsigned long size;35+ struct list_head maps;36+ struct resource rsrc;37+ struct pci_dev *pdev;38+};39+40+struct ck804xrom_map_info {41+ struct list_head list;42+ struct map_info map;43+ struct mtd_info *mtd;44+ struct resource rsrc;45+ char map_name[sizeof(MOD_NAME) + 2 + ADDRESS_NAME_LEN];46+};47+48+49+/* The 2 bits controlling the window size are often set to allow reading50+ * the BIOS, but too small to allow writing, since the lock registers are51+ * 4MiB lower in the address space than the data.52+ *53+ * This is intended to prevent flashing the bios, perhaps accidentally.54+ *55+ * This parameter allows the normal driver to override the BIOS settings.56+ *57+ * The bits are 6 and 7. If both bits are set, it is a 5MiB window.58+ * If only the 7 Bit is set, it is a 4MiB window. Otherwise, a59+ * 64KiB window.60+ *61+ */62+static uint win_size_bits = 0;63+module_param(win_size_bits, uint, 0);64+MODULE_PARM_DESC(win_size_bits, "ROM window size bits override for 0x88 byte, normally set by BIOS.");65+66+static struct ck804xrom_window ck804xrom_window = {67+ .maps = LIST_HEAD_INIT(ck804xrom_window.maps),68+};69+70+static void ck804xrom_cleanup(struct ck804xrom_window *window)71+{72+ struct ck804xrom_map_info *map, *scratch;73+ u8 byte;74+75+ if (window->pdev) {76+ /* Disable writes through the rom window */77+ pci_read_config_byte(window->pdev, 0x6d, &byte);78+ pci_write_config_byte(window->pdev, 0x6d, byte & ~1);79+ }80+81+ /* Free all of the mtd devices */82+ list_for_each_entry_safe(map, scratch, &window->maps, list) {83+ if (map->rsrc.parent)84+ release_resource(&map->rsrc);85+86+ del_mtd_device(map->mtd);87+ map_destroy(map->mtd);88+ list_del(&map->list);89+ kfree(map);90+ }91+ if (window->rsrc.parent)92+ release_resource(&window->rsrc);93+94+ if (window->virt) {95+ iounmap(window->virt);96+ window->virt = NULL;97+ window->phys = 0;98+ window->size = 0;99+ }100+ pci_dev_put(window->pdev);101+}102+103+104+static int __devinit ck804xrom_init_one (struct pci_dev *pdev,105+ const struct pci_device_id *ent)106+{107+ static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL };108+ u8 byte;109+ struct ck804xrom_window *window = &ck804xrom_window;110+ struct ck804xrom_map_info *map = NULL;111+ unsigned long map_top;112+113+ /* Remember the pci dev I find the window in */114+ window->pdev = pci_dev_get(pdev);115+116+ /* Enable the selected rom window. This is often incorrectly117+ * set up by the BIOS, and the 4MiB offset for the lock registers118+ * requires the full 5MiB of window space.119+ *120+ * This 'write, then read' approach leaves the bits for121+ * other uses of the hardware info.122+ */123+ pci_read_config_byte(pdev, 0x88, &byte);124+ pci_write_config_byte(pdev, 0x88, byte | win_size_bits );125+126+127+ /* Assume the rom window is properly setup, and find it's size */128+ pci_read_config_byte(pdev, 0x88, &byte);129+130+ if ((byte & ((1<<7)|(1<<6))) == ((1<<7)|(1<<6)))131+ window->phys = 0xffb00000; /* 5MiB */132+ else if ((byte & (1<<7)) == (1<<7))133+ window->phys = 0xffc00000; /* 4MiB */134+ else135+ window->phys = 0xffff0000; /* 64KiB */136+137+ window->size = 0xffffffffUL - window->phys + 1UL;138+139+ /*140+ * Try to reserve the window mem region. If this fails then141+ * it is likely due to a fragment of the window being142+ * "reserved" by the BIOS. In the case that the143+ * request_mem_region() fails then once the rom size is144+ * discovered we will try to reserve the unreserved fragment.145+ */146+ window->rsrc.name = MOD_NAME;147+ window->rsrc.start = window->phys;148+ window->rsrc.end = window->phys + window->size - 1;149+ window->rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;150+ if (request_resource(&iomem_resource, &window->rsrc)) {151+ window->rsrc.parent = NULL;152+ printk(KERN_ERR MOD_NAME153+ " %s(): Unable to register resource"154+ " 0x%.016llx-0x%.016llx - kernel bug?\n",155+ __func__,156+ (unsigned long long)window->rsrc.start,157+ (unsigned long long)window->rsrc.end);158+ }159+160+161+ /* Enable writes through the rom window */162+ pci_read_config_byte(pdev, 0x6d, &byte);163+ pci_write_config_byte(pdev, 0x6d, byte | 1);164+165+ /* FIXME handle registers 0x80 - 0x8C the bios region locks */166+167+ /* For write accesses caches are useless */168+ window->virt = ioremap_nocache(window->phys, window->size);169+ if (!window->virt) {170+ printk(KERN_ERR MOD_NAME ": ioremap(%08lx, %08lx) failed\n",171+ window->phys, window->size);172+ goto out;173+ }174+175+ /* Get the first address to look for a rom chip at */176+ map_top = window->phys;177+#if 1178+ /* The probe sequence run over the firmware hub lock179+ * registers sets them to 0x7 (no access).180+ * Probe at most the last 4MiB of the address space.181+ */182+ if (map_top < 0xffc00000)183+ map_top = 0xffc00000;184+#endif185+ /* Loop through and look for rom chips. Since we don't know the186+ * starting address for each chip, probe every ROM_PROBE_STEP_SIZE187+ * bytes from the starting address of the window.188+ */189+ while((map_top - 1) < 0xffffffffUL) {190+ struct cfi_private *cfi;191+ unsigned long offset;192+ int i;193+194+ if (!map)195+ map = kmalloc(sizeof(*map), GFP_KERNEL);196+197+ if (!map) {198+ printk(KERN_ERR MOD_NAME ": kmalloc failed");199+ goto out;200+ }201+ memset(map, 0, sizeof(*map));202+ INIT_LIST_HEAD(&map->list);203+ map->map.name = map->map_name;204+ map->map.phys = map_top;205+ offset = map_top - window->phys;206+ map->map.virt = (void __iomem *)207+ (((unsigned long)(window->virt)) + offset);208+ map->map.size = 0xffffffffUL - map_top + 1UL;209+ /* Set the name of the map to the address I am trying */210+ sprintf(map->map_name, "%s @%08lx",211+ MOD_NAME, map->map.phys);212+213+ /* There is no generic VPP support */214+ for(map->map.bankwidth = 32; map->map.bankwidth;215+ map->map.bankwidth >>= 1)216+ {217+ char **probe_type;218+ /* Skip bankwidths that are not supported */219+ if (!map_bankwidth_supported(map->map.bankwidth))220+ continue;221+222+ /* Setup the map methods */223+ simple_map_init(&map->map);224+225+ /* Try all of the probe methods */226+ probe_type = rom_probe_types;227+ for(; *probe_type; probe_type++) {228+ map->mtd = do_map_probe(*probe_type, &map->map);229+ if (map->mtd)230+ goto found;231+ }232+ }233+ map_top += ROM_PROBE_STEP_SIZE;234+ continue;235+ found:236+ /* Trim the size if we are larger than the map */237+ if (map->mtd->size > map->map.size) {238+ printk(KERN_WARNING MOD_NAME239+ " rom(%u) larger than window(%lu). fixing...\n",240+ map->mtd->size, map->map.size);241+ map->mtd->size = map->map.size;242+ }243+ if (window->rsrc.parent) {244+ /*245+ * Registering the MTD device in iomem may not be possible246+ * if there is a BIOS "reserved" and BUSY range. If this247+ * fails then continue anyway.248+ */249+ map->rsrc.name = map->map_name;250+ map->rsrc.start = map->map.phys;251+ map->rsrc.end = map->map.phys + map->mtd->size - 1;252+ map->rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY;253+ if (request_resource(&window->rsrc, &map->rsrc)) {254+ printk(KERN_ERR MOD_NAME255+ ": cannot reserve MTD resource\n");256+ map->rsrc.parent = NULL;257+ }258+ }259+260+ /* Make the whole region visible in the map */261+ map->map.virt = window->virt;262+ map->map.phys = window->phys;263+ cfi = map->map.fldrv_priv;264+ for(i = 0; i < cfi->numchips; i++)265+ cfi->chips[i].start += offset;266+267+ /* Now that the mtd devices is complete claim and export it */268+ map->mtd->owner = THIS_MODULE;269+ if (add_mtd_device(map->mtd)) {270+ map_destroy(map->mtd);271+ map->mtd = NULL;272+ goto out;273+ }274+275+276+ /* Calculate the new value of map_top */277+ map_top += map->mtd->size;278+279+ /* File away the map structure */280+ list_add(&map->list, &window->maps);281+ map = NULL;282+ }283+284+ out:285+ /* Free any left over map structures */286+ if (map)287+ kfree(map);288+289+ /* See if I have any map structures */290+ if (list_empty(&window->maps)) {291+ ck804xrom_cleanup(window);292+ return -ENODEV;293+ }294+ return 0;295+}296+297+298+static void __devexit ck804xrom_remove_one (struct pci_dev *pdev)299+{300+ struct ck804xrom_window *window = &ck804xrom_window;301+302+ ck804xrom_cleanup(window);303+}304+305+static struct pci_device_id ck804xrom_pci_tbl[] = {306+ { PCI_VENDOR_ID_NVIDIA, 0x0051,307+ PCI_ANY_ID, PCI_ANY_ID, }, /* nvidia ck804 */308+ { 0, }309+};310+311+MODULE_DEVICE_TABLE(pci, ck804xrom_pci_tbl);312+313+#if 0314+static struct pci_driver ck804xrom_driver = {315+ .name = MOD_NAME,316+ .id_table = ck804xrom_pci_tbl,317+ .probe = ck804xrom_init_one,318+ .remove = ck804xrom_remove_one,319+};320+#endif321+322+static int __init init_ck804xrom(void)323+{324+ struct pci_dev *pdev;325+ struct pci_device_id *id;326+ int retVal;327+ pdev = NULL;328+329+ for(id = ck804xrom_pci_tbl; id->vendor; id++) {330+ pdev = pci_find_device(id->vendor, id->device, NULL);331+ if (pdev)332+ break;333+ }334+ if (pdev) {335+ retVal = ck804xrom_init_one(pdev, &ck804xrom_pci_tbl[0]);336+ pci_dev_put(pdev);337+ return retVal;338+ }339+ return -ENXIO;340+#if 0341+ return pci_module_init(&ck804xrom_driver);342+#endif343+}344+345+static void __exit cleanup_ck804xrom(void)346+{347+ ck804xrom_remove_one(ck804xrom_window.pdev);348+}349+350+module_init(init_ck804xrom);351+module_exit(cleanup_ck804xrom);352+353+MODULE_LICENSE("GPL");354+MODULE_AUTHOR("Eric Biederman <ebiederman@lnxi.com>, Dave Olsen <dolsen@lnxi.com>");355+MODULE_DESCRIPTION("MTD map driver for BIOS chips on the Nvidia ck804 southbridge");356+
-283
drivers/mtd/maps/cstm_mips_ixx.c
···1-/*2- * $Id: cstm_mips_ixx.c,v 1.14 2005/11/07 11:14:26 gleixner Exp $3- *4- * Mapping of a custom board with both AMD CFI and JEDEC flash in partitions.5- * Config with both CFI and JEDEC device support.6- *7- * Basically physmap.c with the addition of partitions and8- * an array of mapping info to accomodate more than one flash type per board.9- *10- * Copyright 2000 MontaVista Software Inc.11- *12- * This program is free software; you can redistribute it and/or modify it13- * under the terms of the GNU General Public License as published by the14- * Free Software Foundation; either version 2 of the License, or (at your15- * option) any later version.16- *17- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED18- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF19- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN20- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,21- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT22- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF23- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON24- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT25- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF26- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.27- *28- * You should have received a copy of the GNU General Public License along29- * with this program; if not, write to the Free Software Foundation, Inc.,30- * 675 Mass Ave, Cambridge, MA 02139, USA.31- */32-33-#include <linux/module.h>34-#include <linux/types.h>35-#include <linux/kernel.h>36-#include <linux/init.h>37-#include <asm/io.h>38-#include <linux/mtd/mtd.h>39-#include <linux/mtd/map.h>40-#include <linux/mtd/partitions.h>41-#include <linux/delay.h>42-43-#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)44-#define CC_GCR 0xB401381845-#define CC_GPBCR 0xB401380A46-#define CC_GPBDR 0xB401380847-#define CC_M68K_DEVICE 148-#define CC_M68K_FUNCTION 649-#define CC_CONFADDR 0xB800400050-#define CC_CONFDATA 0xB800400451-#define CC_FC_FCR 0xB800200452-#define CC_FC_DCR 0xB800200853-#define CC_GPACR 0xB401380254-#define CC_GPAICR 0xB401380455-#endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */56-57-#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)58-void cstm_mips_ixx_set_vpp(struct map_info *map,int vpp)59-{60- static DEFINE_SPINLOCK(vpp_lock);61- static int vpp_count = 0;62- unsigned long flags;63-64- spin_lock_irqsave(&vpp_lock, flags);65-66- if (vpp) {67- if (!vpp_count++) {68- __u16 data;69- __u8 data1;70- static u8 first = 1;71-72- // Set GPIO port B pin3 to high73- data = *(__u16 *)(CC_GPBCR);74- data = (data & 0xff0f) | 0x0040;75- *(__u16 *)CC_GPBCR = data;76- *(__u8 *)CC_GPBDR = (*(__u8*)CC_GPBDR) | 0x08;77- if (first) {78- first = 0;79- /* need to have this delay for first80- enabling vpp after powerup */81- udelay(40);82- }83- }84- } else {85- if (!--vpp_count) {86- __u16 data;87-88- // Set GPIO port B pin3 to high89- data = *(__u16 *)(CC_GPBCR);90- data = (data & 0xff3f) | 0x0040;91- *(__u16 *)CC_GPBCR = data;92- *(__u8 *)CC_GPBDR = (*(__u8*)CC_GPBDR) & 0xf7;93- }94- }95- spin_unlock_irqrestore(&vpp_lock, flags);96-}97-#endif98-99-/* board and partition description */100-101-#define MAX_PHYSMAP_PARTITIONS 8102-struct cstm_mips_ixx_info {103- char *name;104- unsigned long window_addr;105- unsigned long window_size;106- int bankwidth;107- int num_partitions;108-};109-110-#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)111-#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type112-const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =113-{114- { // 28F128J3A in 2x16 configuration115- "big flash", // name116- 0x08000000, // window_addr117- 0x02000000, // window_size118- 4, // bankwidth119- 1, // num_partitions120- }121-122-};123-static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {124-{ // 28F128J3A in 2x16 configuration125- {126- .name = "main partition ",127- .size = 0x02000000, // 128 x 2 x 128k byte sectors128- .offset = 0,129- },130-},131-};132-#else /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */133-#define PHYSMAP_NUMBER 1 // number of board desc structs needed, one per contiguous flash type134-const struct cstm_mips_ixx_info cstm_mips_ixx_board_desc[PHYSMAP_NUMBER] =135-{136- {137- "MTD flash", // name138- CONFIG_MTD_CSTM_MIPS_IXX_START, // window_addr139- CONFIG_MTD_CSTM_MIPS_IXX_LEN, // window_size140- CONFIG_MTD_CSTM_MIPS_IXX_BUSWIDTH, // bankwidth141- 1, // num_partitions142- },143-144-};145-static struct mtd_partition cstm_mips_ixx_partitions[PHYSMAP_NUMBER][MAX_PHYSMAP_PARTITIONS] = {146-{147- {148- .name = "main partition",149- .size = CONFIG_MTD_CSTM_MIPS_IXX_LEN,150- .offset = 0,151- },152-},153-};154-#endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */155-156-struct map_info cstm_mips_ixx_map[PHYSMAP_NUMBER];157-158-int __init init_cstm_mips_ixx(void)159-{160- int i;161- int jedec;162- struct mtd_info *mymtd;163- struct mtd_partition *parts;164-165- /* Initialize mapping */166- for (i=0;i<PHYSMAP_NUMBER;i++) {167- printk(KERN_NOTICE "cstm_mips_ixx flash device: 0x%lx at 0x%lx\n",168- cstm_mips_ixx_board_desc[i].window_size, cstm_mips_ixx_board_desc[i].window_addr);169-170-171- cstm_mips_ixx_map[i].phys = cstm_mips_ixx_board_desc[i].window_addr;172- cstm_mips_ixx_map[i].virt = ioremap(cstm_mips_ixx_board_desc[i].window_addr, cstm_mips_ixx_board_desc[i].window_size);173- if (!cstm_mips_ixx_map[i].virt) {174- int j = 0;175- printk(KERN_WARNING "Failed to ioremap\n");176- for (j = 0; j < i; j++) {177- if (cstm_mips_ixx_map[j].virt) {178- iounmap(cstm_mips_ixx_map[j].virt);179- cstm_mips_ixx_map[j].virt = NULL;180- }181- }182- return -EIO;183- }184- cstm_mips_ixx_map[i].name = cstm_mips_ixx_board_desc[i].name;185- cstm_mips_ixx_map[i].size = cstm_mips_ixx_board_desc[i].window_size;186- cstm_mips_ixx_map[i].bankwidth = cstm_mips_ixx_board_desc[i].bankwidth;187-#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)188- cstm_mips_ixx_map[i].set_vpp = cstm_mips_ixx_set_vpp;189-#endif190- simple_map_init(&cstm_mips_ixx_map[i]);191- //printk(KERN_NOTICE "cstm_mips_ixx: ioremap is %x\n",(unsigned int)(cstm_mips_ixx_map[i].virt));192- }193-194-#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)195- setup_ITE_IVR_flash();196-#endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */197-198- for (i=0;i<PHYSMAP_NUMBER;i++) {199- parts = &cstm_mips_ixx_partitions[i][0];200- jedec = 0;201- mymtd = (struct mtd_info *)do_map_probe("cfi_probe", &cstm_mips_ixx_map[i]);202- //printk(KERN_NOTICE "phymap %d cfi_probe: mymtd is %x\n",i,(unsigned int)mymtd);203- if (!mymtd) {204- jedec = 1;205- mymtd = (struct mtd_info *)do_map_probe("jedec", &cstm_mips_ixx_map[i]);206- printk(KERN_NOTICE "cstm_mips_ixx %d jedec: mymtd is %x\n",i,(unsigned int)mymtd);207- }208- if (mymtd) {209- mymtd->owner = THIS_MODULE;210-211- cstm_mips_ixx_map[i].map_priv_2 = (unsigned long)mymtd;212- add_mtd_partitions(mymtd, parts, cstm_mips_ixx_board_desc[i].num_partitions);213- }214- else {215- for (i = 0; i < PHYSMAP_NUMBER; i++) {216- if (cstm_mips_ixx_map[i].virt) {217- iounmap(cstm_mips_ixx_map[i].virt);218- cstm_mips_ixx_map[i].virt = NULL;219- }220- }221- return -ENXIO;222- }223- }224- return 0;225-}226-227-static void __exit cleanup_cstm_mips_ixx(void)228-{229- int i;230- struct mtd_info *mymtd;231-232- for (i=0;i<PHYSMAP_NUMBER;i++) {233- mymtd = (struct mtd_info *)cstm_mips_ixx_map[i].map_priv_2;234- if (mymtd) {235- del_mtd_partitions(mymtd);236- map_destroy(mymtd);237- }238- if (cstm_mips_ixx_map[i].virt) {239- iounmap((void *)cstm_mips_ixx_map[i].virt);240- cstm_mips_ixx_map[i].virt = 0;241- }242- }243-}244-#if defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR)245-void PCISetULongByOffset(__u32 DevNumber, __u32 FuncNumber, __u32 Offset, __u32 data)246-{247- __u32 offset;248-249- offset = ( unsigned long )( 0x80000000 | ( DevNumber << 11 ) + ( FuncNumber << 8 ) + Offset) ;250-251- *(__u32 *)CC_CONFADDR = offset;252- *(__u32 *)CC_CONFDATA = data;253-}254-void setup_ITE_IVR_flash()255-{256- __u32 size, base;257-258- size = 0x0e000000; // 32MiB259- base = (0x08000000) >> 8 >>1; // Bug: we must shift one more bit260-261- /* need to set ITE flash to 32 bits instead of default 8 */262-#ifdef CONFIG_MIPS_IVR263- *(__u32 *)CC_FC_FCR = 0x55;264- *(__u32 *)CC_GPACR = 0xfffc;265-#else266- *(__u32 *)CC_FC_FCR = 0x77;267-#endif268- /* turn bursting off */269- *(__u32 *)CC_FC_DCR = 0x0;270-271- /* setup for one chip 4 byte PCI access */272- PCISetULongByOffset(CC_M68K_DEVICE, CC_M68K_FUNCTION, 0x60, size | base);273- PCISetULongByOffset(CC_M68K_DEVICE, CC_M68K_FUNCTION, 0x64, 0x02);274-}275-#endif /* defined(CONFIG_MIPS_ITE8172) || defined(CONFIG_MIPS_IVR) */276-277-module_init(init_cstm_mips_ixx);278-module_exit(cleanup_cstm_mips_ixx);279-280-281-MODULE_LICENSE("GPL");282-MODULE_AUTHOR("Alice Hennessy <ahennessy@mvista.com>");283-MODULE_DESCRIPTION("MTD map driver for ITE 8172G and Globespan IVR boards");
···1+/*2+ * Normal mappings of chips in physical memory for OF devices3+ *4+ * Copyright (C) 2006 MontaVista Software Inc.5+ * Author: Vitaly Wool <vwool@ru.mvista.com>6+ *7+ * This program is free software; you can redistribute it and/or modify it8+ * under the terms of the GNU General Public License as published by the9+ * Free Software Foundation; either version 2 of the License, or (at your10+ * option) any later version.11+ */12+13+#include <linux/module.h>14+#include <linux/types.h>15+#include <linux/kernel.h>16+#include <linux/init.h>17+#include <linux/slab.h>18+#include <linux/device.h>19+#include <linux/mtd/mtd.h>20+#include <linux/mtd/map.h>21+#include <linux/mtd/partitions.h>22+#include <linux/mtd/physmap.h>23+#include <asm/io.h>24+#include <asm/prom.h>25+#include <asm/of_device.h>26+#include <asm/of_platform.h>27+28+struct physmap_flash_info {29+ struct mtd_info *mtd;30+ struct map_info map;31+ struct resource *res;32+#ifdef CONFIG_MTD_PARTITIONS33+ int nr_parts;34+ struct mtd_partition *parts;35+#endif36+};37+38+static const char *rom_probe_types[] = { "cfi_probe", "jedec_probe", "map_rom", NULL };39+#ifdef CONFIG_MTD_PARTITIONS40+static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL };41+#endif42+43+#ifdef CONFIG_MTD_PARTITIONS44+static int parse_flash_partitions(struct device_node *node,45+ struct mtd_partition **parts)46+{47+ int i, plen, retval = -ENOMEM;48+ const u32 *part;49+ const char *name;50+51+ part = get_property(node, "partitions", &plen);52+ if (part == NULL)53+ goto err;54+55+ retval = plen / (2 * sizeof(u32));56+ *parts = kzalloc(retval * sizeof(struct mtd_partition), GFP_KERNEL);57+ if (*parts == NULL) {58+ printk(KERN_ERR "Can't allocate the flash partition data!\n");59+ goto err;60+ }61+62+ name = get_property(node, "partition-names", &plen);63+64+ for (i = 0; i < retval; i++) {65+ (*parts)[i].offset = *part++;66+ (*parts)[i].size = *part & ~1;67+ if (*part++ & 1) /* bit 0 set signifies read only partition */68+ (*parts)[i].mask_flags = MTD_WRITEABLE;69+70+ if (name != NULL && plen > 0) {71+ int len = strlen(name) + 1;72+73+ (*parts)[i].name = (char *)name;74+ plen -= len;75+ name += len;76+ } else77+ (*parts)[i].name = "unnamed";78+ }79+err:80+ return retval;81+}82+#endif83+84+static int of_physmap_remove(struct of_device *dev)85+{86+ struct physmap_flash_info *info;87+88+ info = dev_get_drvdata(&dev->dev);89+ if (info == NULL)90+ return 0;91+ dev_set_drvdata(&dev->dev, NULL);92+93+ if (info->mtd != NULL) {94+#ifdef CONFIG_MTD_PARTITIONS95+ if (info->nr_parts) {96+ del_mtd_partitions(info->mtd);97+ kfree(info->parts);98+ } else {99+ del_mtd_device(info->mtd);100+ }101+#else102+ del_mtd_device(info->mtd);103+#endif104+ map_destroy(info->mtd);105+ }106+107+ if (info->map.virt != NULL)108+ iounmap(info->map.virt);109+110+ if (info->res != NULL) {111+ release_resource(info->res);112+ kfree(info->res);113+ }114+115+ return 0;116+}117+118+static int __devinit of_physmap_probe(struct of_device *dev, const struct of_device_id *match)119+{120+ struct device_node *dp = dev->node;121+ struct resource res;122+ struct physmap_flash_info *info;123+ const char **probe_type;124+ const char *of_probe;125+ const u32 *width;126+ int err;127+128+129+ if (of_address_to_resource(dp, 0, &res)) {130+ dev_err(&dev->dev, "Can't get the flash mapping!\n");131+ err = -EINVAL;132+ goto err_out;133+ }134+135+ dev_dbg(&dev->dev, "physmap flash device: %.8llx at %.8llx\n",136+ (unsigned long long)res.end - res.start + 1,137+ (unsigned long long)res.start);138+139+ info = kzalloc(sizeof(struct physmap_flash_info), GFP_KERNEL);140+ if (info == NULL) {141+ err = -ENOMEM;142+ goto err_out;143+ }144+ memset(info, 0, sizeof(*info));145+146+ dev_set_drvdata(&dev->dev, info);147+148+ info->res = request_mem_region(res.start, res.end - res.start + 1,149+ dev->dev.bus_id);150+ if (info->res == NULL) {151+ dev_err(&dev->dev, "Could not reserve memory region\n");152+ err = -ENOMEM;153+ goto err_out;154+ }155+156+ width = get_property(dp, "bank-width", NULL);157+ if (width == NULL) {158+ dev_err(&dev->dev, "Can't get the flash bank width!\n");159+ err = -EINVAL;160+ goto err_out;161+ }162+163+ info->map.name = dev->dev.bus_id;164+ info->map.phys = res.start;165+ info->map.size = res.end - res.start + 1;166+ info->map.bankwidth = *width;167+168+ info->map.virt = ioremap(info->map.phys, info->map.size);169+ if (info->map.virt == NULL) {170+ dev_err(&dev->dev, "Failed to ioremap flash region\n");171+ err = EIO;172+ goto err_out;173+ }174+175+ simple_map_init(&info->map);176+177+ of_probe = get_property(dp, "probe-type", NULL);178+ if (of_probe == NULL) {179+ probe_type = rom_probe_types;180+ for (; info->mtd == NULL && *probe_type != NULL; probe_type++)181+ info->mtd = do_map_probe(*probe_type, &info->map);182+ } else if (!strcmp(of_probe, "CFI"))183+ info->mtd = do_map_probe("cfi_probe", &info->map);184+ else if (!strcmp(of_probe, "JEDEC"))185+ info->mtd = do_map_probe("jedec_probe", &info->map);186+ else {187+ if (strcmp(of_probe, "ROM"))188+ dev_dbg(&dev->dev, "map_probe: don't know probe type "189+ "'%s', mapping as rom\n");190+ info->mtd = do_map_probe("mtd_rom", &info->map);191+ }192+ if (info->mtd == NULL) {193+ dev_err(&dev->dev, "map_probe failed\n");194+ err = -ENXIO;195+ goto err_out;196+ }197+ info->mtd->owner = THIS_MODULE;198+199+#ifdef CONFIG_MTD_PARTITIONS200+ err = parse_mtd_partitions(info->mtd, part_probe_types, &info->parts, 0);201+ if (err > 0) {202+ add_mtd_partitions(info->mtd, info->parts, err);203+ } else if ((err = parse_flash_partitions(dp, &info->parts)) > 0) {204+ dev_info(&dev->dev, "Using OF partition information\n");205+ add_mtd_partitions(info->mtd, info->parts, err);206+ info->nr_parts = err;207+ } else208+#endif209+210+ add_mtd_device(info->mtd);211+ return 0;212+213+err_out:214+ of_physmap_remove(dev);215+ return err;216+217+ return 0;218+219+220+}221+222+static struct of_device_id of_physmap_match[] = {223+ {224+ .type = "rom",225+ .compatible = "direct-mapped"226+ },227+ { },228+};229+230+MODULE_DEVICE_TABLE(of, of_physmap_match);231+232+233+static struct of_platform_driver of_physmap_flash_driver = {234+ .name = "physmap-flash",235+ .match_table = of_physmap_match,236+ .probe = of_physmap_probe,237+ .remove = of_physmap_remove,238+};239+240+static int __init of_physmap_init(void)241+{242+ return of_register_platform_driver(&of_physmap_flash_driver);243+}244+245+static void __exit of_physmap_exit(void)246+{247+ of_unregister_platform_driver(&of_physmap_flash_driver);248+}249+250+module_init(of_physmap_init);251+module_exit(of_physmap_exit);252+253+MODULE_LICENSE("GPL");254+MODULE_AUTHOR("Vitaly Wool <vwool@ru.mvista.com>");255+MODULE_DESCRIPTION("Configurable MTD map driver for OF");
+1-2
drivers/mtd/maps/plat-ram.c
···147148 pdata = pdev->dev.platform_data;149150- info = kmalloc(sizeof(*info), GFP_KERNEL);151 if (info == NULL) {152 dev_err(&pdev->dev, "no memory for flash info\n");153 err = -ENOMEM;154 goto exit_error;155 }156157- memset(info, 0, sizeof(*info));158 platform_set_drvdata(pdev, info);159160 info->dev = &pdev->dev;
···147148 pdata = pdev->dev.platform_data;149150+ info = kzalloc(sizeof(*info), GFP_KERNEL);151 if (info == NULL) {152 dev_err(&pdev->dev, "no memory for flash info\n");153 err = -ENOMEM;154 goto exit_error;155 }1560157 platform_set_drvdata(pdev, info);158159 info->dev = &pdev->dev;
+1-3
drivers/mtd/maps/sa1100-flash.c
···273 /*274 * Allocate the map_info structs in one go.275 */276- info = kmalloc(size, GFP_KERNEL);277 if (!info) {278 ret = -ENOMEM;279 goto out;280 }281-282- memset(info, 0, size);283284 if (plat->init) {285 ret = plat->init();
···273 /*274 * Allocate the map_info structs in one go.275 */276+ info = kzalloc(size, GFP_KERNEL);277 if (!info) {278 ret = -ENOMEM;279 goto out;280 }00281282 if (plat->init) {283 ret = plat->init();
···78#include <linux/device.h>9#include <linux/fs.h>010#include <linux/init.h>11#include <linux/kernel.h>12#include <linux/module.h>···101102 mtd = get_mtd_device(NULL, devnum);103104- if (!mtd)105- return -ENODEV;106107 if (MTD_ABSENT == mtd->type) {108 put_mtd_device(mtd);···432 if(!(file->f_mode & 2))433 return -EPERM;434435- erase=kmalloc(sizeof(struct erase_info),GFP_KERNEL);436 if (!erase)437 ret = -ENOMEM;438 else {···441442 init_waitqueue_head(&waitq);443444- memset (erase,0,sizeof(struct erase_info));445 if (copy_from_user(&erase->addr, argp,446 sizeof(struct erase_info_user))) {447 kfree(erase);···499 if (ret)500 return ret;501502- ops.len = buf.length;503 ops.ooblen = buf.length;504 ops.ooboffs = buf.start & (mtd->oobsize - 1);505 ops.datbuf = NULL;506 ops.mode = MTD_OOB_PLACE;507508- if (ops.ooboffs && ops.len > (mtd->oobsize - ops.ooboffs))509 return -EINVAL;510511 ops.oobbuf = kmalloc(buf.length, GFP_KERNEL);···519 buf.start &= ~(mtd->oobsize - 1);520 ret = mtd->write_oob(mtd, buf.start, &ops);521522- if (copy_to_user(argp + sizeof(uint32_t), &ops.retlen,523 sizeof(uint32_t)))524 ret = -EFAULT;525···547 if (ret)548 return ret;549550- ops.len = buf.length;551 ops.ooblen = buf.length;552 ops.ooboffs = buf.start & (mtd->oobsize - 1);553 ops.datbuf = NULL;···562 buf.start &= ~(mtd->oobsize - 1);563 ret = mtd->read_oob(mtd, buf.start, &ops);564565- if (put_user(ops.retlen, (uint32_t __user *)argp))566 ret = -EFAULT;567- else if (ops.retlen && copy_to_user(buf.ptr, ops.oobbuf,568- ops.retlen))569 ret = -EFAULT;570571 kfree(ops.oobbuf);···614 memcpy(&oi.eccpos, mtd->ecclayout->eccpos, sizeof(oi.eccpos));615 memcpy(&oi.oobfree, mtd->ecclayout->oobfree,616 sizeof(oi.oobfree));0617618 if (copy_to_user(argp, &oi, sizeof(struct nand_oobinfo)))619 return -EFAULT;···714 if (!mtd->ecclayout)715 return -EOPNOTSUPP;716717- if (copy_to_user(argp, &mtd->ecclayout,718 sizeof(struct nand_ecclayout)))719 return -EFAULT;720 break;
···78#include <linux/device.h>9#include <linux/fs.h>10+#include <linux/err.h>11#include <linux/init.h>12#include <linux/kernel.h>13#include <linux/module.h>···100101 mtd = get_mtd_device(NULL, devnum);102103+ if (IS_ERR(mtd))104+ return PTR_ERR(mtd);105106 if (MTD_ABSENT == mtd->type) {107 put_mtd_device(mtd);···431 if(!(file->f_mode & 2))432 return -EPERM;433434+ erase=kzalloc(sizeof(struct erase_info),GFP_KERNEL);435 if (!erase)436 ret = -ENOMEM;437 else {···440441 init_waitqueue_head(&waitq);4420443 if (copy_from_user(&erase->addr, argp,444 sizeof(struct erase_info_user))) {445 kfree(erase);···499 if (ret)500 return ret;5010502 ops.ooblen = buf.length;503 ops.ooboffs = buf.start & (mtd->oobsize - 1);504 ops.datbuf = NULL;505 ops.mode = MTD_OOB_PLACE;506507+ if (ops.ooboffs && ops.ooblen > (mtd->oobsize - ops.ooboffs))508 return -EINVAL;509510 ops.oobbuf = kmalloc(buf.length, GFP_KERNEL);···520 buf.start &= ~(mtd->oobsize - 1);521 ret = mtd->write_oob(mtd, buf.start, &ops);522523+ if (copy_to_user(argp + sizeof(uint32_t), &ops.oobretlen,524 sizeof(uint32_t)))525 ret = -EFAULT;526···548 if (ret)549 return ret;5500551 ops.ooblen = buf.length;552 ops.ooboffs = buf.start & (mtd->oobsize - 1);553 ops.datbuf = NULL;···564 buf.start &= ~(mtd->oobsize - 1);565 ret = mtd->read_oob(mtd, buf.start, &ops);566567+ if (put_user(ops.oobretlen, (uint32_t __user *)argp))568 ret = -EFAULT;569+ else if (ops.oobretlen && copy_to_user(buf.ptr, ops.oobbuf,570+ ops.oobretlen))571 ret = -EFAULT;572573 kfree(ops.oobbuf);···616 memcpy(&oi.eccpos, mtd->ecclayout->eccpos, sizeof(oi.eccpos));617 memcpy(&oi.oobfree, mtd->ecclayout->oobfree,618 sizeof(oi.oobfree));619+ oi.eccbytes = mtd->ecclayout->eccbytes;620621 if (copy_to_user(argp, &oi, sizeof(struct nand_oobinfo)))622 return -EFAULT;···715 if (!mtd->ecclayout)716 return -EOPNOTSUPP;717718+ if (copy_to_user(argp, mtd->ecclayout,719 sizeof(struct nand_ecclayout)))720 return -EFAULT;721 break;
+26-17
drivers/mtd/mtdconcat.c
···247 struct mtd_oob_ops devops = *ops;248 int i, err, ret = 0;249250- ops->retlen = 0;251252 for (i = 0; i < concat->num_subdev; i++) {253 struct mtd_info *subdev = concat->subdev[i];···263264 err = subdev->read_oob(subdev, from, &devops);265 ops->retlen += devops.retlen;0266267 /* Save information about bitflips! */268 if (unlikely(err)) {···279 return err;280 }281282- devops.len = ops->len - ops->retlen;283- if (!devops.len)284- return ret;285-286- if (devops.datbuf)287 devops.datbuf += devops.retlen;288- if (devops.oobbuf)289- devops.oobbuf += devops.ooblen;00000290291 from = 0;292 }···326 if (err)327 return err;328329- devops.len = ops->len - ops->retlen;330- if (!devops.len)331- return 0;332-333- if (devops.datbuf)334 devops.datbuf += devops.retlen;335- if (devops.oobbuf)336- devops.oobbuf += devops.ooblen;00000337 to = 0;338 }339 return -EINVAL;···708709 /* allocate the device structure */710 size = SIZEOF_STRUCT_MTD_CONCAT(num_devs);711- concat = kmalloc(size, GFP_KERNEL);712 if (!concat) {713 printk714 ("memory allocation error while creating concatenated device \"%s\"\n",715 name);716 return NULL;717 }718- memset(concat, 0, size);719 concat->subdev = (struct mtd_info **) (concat + 1);720721 /*···772 concat->mtd.ecc_stats.badblocks +=773 subdev[i]->ecc_stats.badblocks;774 if (concat->mtd.writesize != subdev[i]->writesize ||0775 concat->mtd.oobsize != subdev[i]->oobsize ||776 concat->mtd.ecctype != subdev[i]->ecctype ||777 concat->mtd.eccsize != subdev[i]->eccsize ||
···247 struct mtd_oob_ops devops = *ops;248 int i, err, ret = 0;249250+ ops->retlen = ops->oobretlen = 0;251252 for (i = 0; i < concat->num_subdev; i++) {253 struct mtd_info *subdev = concat->subdev[i];···263264 err = subdev->read_oob(subdev, from, &devops);265 ops->retlen += devops.retlen;266+ ops->oobretlen += devops.oobretlen;267268 /* Save information about bitflips! */269 if (unlikely(err)) {···278 return err;279 }280281+ if (devops.datbuf) {282+ devops.len = ops->len - ops->retlen;283+ if (!devops.len)284+ return ret;0285 devops.datbuf += devops.retlen;286+ }287+ if (devops.oobbuf) {288+ devops.ooblen = ops->ooblen - ops->oobretlen;289+ if (!devops.ooblen)290+ return ret;291+ devops.oobbuf += ops->oobretlen;292+ }293294 from = 0;295 }···321 if (err)322 return err;323324+ if (devops.datbuf) {325+ devops.len = ops->len - ops->retlen;326+ if (!devops.len)327+ return 0;0328 devops.datbuf += devops.retlen;329+ }330+ if (devops.oobbuf) {331+ devops.ooblen = ops->ooblen - ops->oobretlen;332+ if (!devops.ooblen)333+ return 0;334+ devops.oobbuf += devops.oobretlen;335+ }336 to = 0;337 }338 return -EINVAL;···699700 /* allocate the device structure */701 size = SIZEOF_STRUCT_MTD_CONCAT(num_devs);702+ concat = kzalloc(size, GFP_KERNEL);703 if (!concat) {704 printk705 ("memory allocation error while creating concatenated device \"%s\"\n",706 name);707 return NULL;708 }0709 concat->subdev = (struct mtd_info **) (concat + 1);710711 /*···764 concat->mtd.ecc_stats.badblocks +=765 subdev[i]->ecc_stats.badblocks;766 if (concat->mtd.writesize != subdev[i]->writesize ||767+ concat->mtd.subpage_sft != subdev[i]->subpage_sft ||768 concat->mtd.oobsize != subdev[i]->oobsize ||769 concat->mtd.ecctype != subdev[i]->ecctype ||770 concat->mtd.eccsize != subdev[i]->eccsize ||
+78-15
drivers/mtd/mtdcore.c
···15#include <linux/timer.h>16#include <linux/major.h>17#include <linux/fs.h>018#include <linux/ioctl.h>19#include <linux/init.h>20#include <linux/mtd/compatmac.h>···193 * Given a number and NULL address, return the num'th entry in the device194 * table, if any. Given an address and num == -1, search the device table195 * for a device with that address and return if it's still present. Given196- * both, return the num'th driver only if its address matches. Return NULL197- * if not.198 */199200struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)201{202 struct mtd_info *ret = NULL;203- int i;204205 mutex_lock(&mtd_table_mutex);206···214 ret = NULL;215 }216217- if (ret && !try_module_get(ret->owner))218- ret = NULL;219220- if (ret)221- ret->usecount++;2220000000223 mutex_unlock(&mtd_table_mutex);224 return ret;0000000000000000000000000000000000000000000000000000225}226227void put_mtd_device(struct mtd_info *mtd)···289290 mutex_lock(&mtd_table_mutex);291 c = --mtd->usecount;00292 mutex_unlock(&mtd_table_mutex);293 BUG_ON(c < 0);294···298}299300/* default_mtd_writev - default mtd writev method for MTD devices that301- * dont implement their own302 */303304int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,···326 return ret;327}328329-EXPORT_SYMBOL(add_mtd_device);330-EXPORT_SYMBOL(del_mtd_device);331-EXPORT_SYMBOL(get_mtd_device);332-EXPORT_SYMBOL(put_mtd_device);333-EXPORT_SYMBOL(register_mtd_user);334-EXPORT_SYMBOL(unregister_mtd_user);335-EXPORT_SYMBOL(default_mtd_writev);0336337#ifdef CONFIG_PROC_FS338
···15#include <linux/timer.h>16#include <linux/major.h>17#include <linux/fs.h>18+#include <linux/err.h>19#include <linux/ioctl.h>20#include <linux/init.h>21#include <linux/mtd/compatmac.h>···192 * Given a number and NULL address, return the num'th entry in the device193 * table, if any. Given an address and num == -1, search the device table194 * for a device with that address and return if it's still present. Given195+ * both, return the num'th driver only if its address matches. Return196+ * error code if not.197 */198199struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)200{201 struct mtd_info *ret = NULL;202+ int i, err = -ENODEV;203204 mutex_lock(&mtd_table_mutex);205···213 ret = NULL;214 }215216+ if (!ret)217+ goto out_unlock;218219+ if (!try_module_get(ret->owner))220+ goto out_unlock;221222+ if (ret->get_device) {223+ err = ret->get_device(ret);224+ if (err)225+ goto out_put;226+ }227+228+ ret->usecount++;229 mutex_unlock(&mtd_table_mutex);230 return ret;231+232+out_put:233+ module_put(ret->owner);234+out_unlock:235+ mutex_unlock(&mtd_table_mutex);236+ return ERR_PTR(err);237+}238+239+/**240+ * get_mtd_device_nm - obtain a validated handle for an MTD device by241+ * device name242+ * @name: MTD device name to open243+ *244+ * This function returns MTD device description structure in case of245+ * success and an error code in case of failure.246+ */247+248+struct mtd_info *get_mtd_device_nm(const char *name)249+{250+ int i, err = -ENODEV;251+ struct mtd_info *mtd = NULL;252+253+ mutex_lock(&mtd_table_mutex);254+255+ for (i = 0; i < MAX_MTD_DEVICES; i++) {256+ if (mtd_table[i] && !strcmp(name, mtd_table[i]->name)) {257+ mtd = mtd_table[i];258+ break;259+ }260+ }261+262+ if (!mtd)263+ goto out_unlock;264+265+ if (!try_module_get(mtd->owner))266+ goto out_unlock;267+268+ if (mtd->get_device) {269+ err = mtd->get_device(mtd);270+ if (err)271+ goto out_put;272+ }273+274+ mtd->usecount++;275+ mutex_unlock(&mtd_table_mutex);276+ return mtd;277+278+out_put:279+ module_put(mtd->owner);280+out_unlock:281+ mutex_unlock(&mtd_table_mutex);282+ return ERR_PTR(err);283}284285void put_mtd_device(struct mtd_info *mtd)···229230 mutex_lock(&mtd_table_mutex);231 c = --mtd->usecount;232+ if (mtd->put_device)233+ mtd->put_device(mtd);234 mutex_unlock(&mtd_table_mutex);235 BUG_ON(c < 0);236···236}237238/* default_mtd_writev - default mtd writev method for MTD devices that239+ * don't implement their own240 */241242int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,···264 return ret;265}266267+EXPORT_SYMBOL_GPL(add_mtd_device);268+EXPORT_SYMBOL_GPL(del_mtd_device);269+EXPORT_SYMBOL_GPL(get_mtd_device);270+EXPORT_SYMBOL_GPL(get_mtd_device_nm);271+EXPORT_SYMBOL_GPL(put_mtd_device);272+EXPORT_SYMBOL_GPL(register_mtd_user);273+EXPORT_SYMBOL_GPL(unregister_mtd_user);274+EXPORT_SYMBOL_GPL(default_mtd_writev);275276#ifdef CONFIG_PROC_FS277
+4-4
drivers/mtd/mtdpart.c
···9495 if (from >= mtd->size)96 return -EINVAL;97- if (from + ops->len > mtd->size)98 return -EINVAL;99 res = part->master->read_oob(part->master, from + part->offset, ops);100···161162 if (to >= mtd->size)163 return -EINVAL;164- if (to + ops->len > mtd->size)165 return -EINVAL;166 return part->master->write_oob(part->master, to + part->offset, ops);167}···323 for (i = 0; i < nbparts; i++) {324325 /* allocate the partition structure */326- slave = kmalloc (sizeof(*slave), GFP_KERNEL);327 if (!slave) {328 printk ("memory allocation error while creating partitions for \"%s\"\n",329 master->name);330 del_mtd_partitions(master);331 return -ENOMEM;332 }333- memset(slave, 0, sizeof(*slave));334 list_add(&slave->list, &mtd_partitions);335336 /* set up the MTD object for this partition */···340 slave->mtd.oobsize = master->oobsize;341 slave->mtd.ecctype = master->ecctype;342 slave->mtd.eccsize = master->eccsize;0343344 slave->mtd.name = parts[i].name;345 slave->mtd.bank_size = master->bank_size;
···9495 if (from >= mtd->size)96 return -EINVAL;97+ if (ops->datbuf && from + ops->len > mtd->size)98 return -EINVAL;99 res = part->master->read_oob(part->master, from + part->offset, ops);100···161162 if (to >= mtd->size)163 return -EINVAL;164+ if (ops->datbuf && to + ops->len > mtd->size)165 return -EINVAL;166 return part->master->write_oob(part->master, to + part->offset, ops);167}···323 for (i = 0; i < nbparts; i++) {324325 /* allocate the partition structure */326+ slave = kzalloc (sizeof(*slave), GFP_KERNEL);327 if (!slave) {328 printk ("memory allocation error while creating partitions for \"%s\"\n",329 master->name);330 del_mtd_partitions(master);331 return -ENOMEM;332 }0333 list_add(&slave->list, &mtd_partitions);334335 /* set up the MTD object for this partition */···341 slave->mtd.oobsize = master->oobsize;342 slave->mtd.ecctype = master->ecctype;343 slave->mtd.eccsize = master->eccsize;344+ slave->mtd.subpage_sft = master->subpage_sft;345346 slave->mtd.name = parts[i].name;347 slave->mtd.bank_size = master->bank_size;
+16
drivers/mtd/nand/Kconfig
···90 depends on MTD_NAND && SH_SOLUTION_ENGINE91 select REED_SOLOMON92 select REED_SOLOMON_DEC8093 help94 This enables the driver for the Renesas Technology AG-AND95 flash interface board (FROM_BOARD4)···133config MTD_NAND_NDFC134 tristate "NDFC NanD Flash Controller"135 depends on MTD_NAND && 44x0136 help137 NDFC Nand Flash Controllers are integrated in EP44x SoCs138···221 tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)"222 depends on MTD_NAND && ARCH_PXA2230000000224config MTD_NAND_CS553X225 tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)"226 depends on MTD_NAND && X86_32 && (X86_PC || X86_GENERICARCH)···240 the controller be in MMIO mode.241242 If you say "m", the module will be called "cs553x_nand.ko".0000000243244config MTD_NAND_NANDSIM245 tristate "Support for NAND Flash Simulator"
···90 depends on MTD_NAND && SH_SOLUTION_ENGINE91 select REED_SOLOMON92 select REED_SOLOMON_DEC893+ select BITREVERSE94 help95 This enables the driver for the Renesas Technology AG-AND96 flash interface board (FROM_BOARD4)···132config MTD_NAND_NDFC133 tristate "NDFC NanD Flash Controller"134 depends on MTD_NAND && 44x135+ select MTD_NAND_ECC_SMC136 help137 NDFC Nand Flash Controllers are integrated in EP44x SoCs138···219 tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)"220 depends on MTD_NAND && ARCH_PXA221222+config MTD_NAND_CAFE223+ tristate "NAND support for OLPC CAFÉ chip"224+ depends on PCI225+ help226+ Use NAND flash attached to the CAFÉ chip designed for the $100227+ laptop.228+229config MTD_NAND_CS553X230 tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)"231 depends on MTD_NAND && X86_32 && (X86_PC || X86_GENERICARCH)···231 the controller be in MMIO mode.232233 If you say "m", the module will be called "cs553x_nand.ko".234+235+config MTD_NAND_AT91236+ bool "Support for NAND Flash / SmartMedia on AT91"237+ depends on MTD_NAND && ARCH_AT91238+ help239+ Enables support for NAND Flash / Smart Media Card interface240+ on Atmel AT91 processors.241242config MTD_NAND_NANDSIM243 tristate "Support for NAND Flash Simulator"
···11 * published by the Free Software Foundation.12 *13 * Overview:14- * This is a device driver for the NAND flash controller found on 15 * the AMD CS5535/CS5536 companion chipsets for the Geode processor.16 *17 */···303 err = cs553x_init_one(i, !!(val & FLSH_MEM_IO), val & 0xFFFFFFFF);304 }305306- /* Register all devices together here. This means we can easily hack it to 307 do mtdconcat etc. if we want to. */308 for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {309 if (cs553x_mtd[i]) {
···11 * published by the Free Software Foundation.12 *13 * Overview:14+ * This is a device driver for the NAND flash controller found on15 * the AMD CS5535/CS5536 companion chipsets for the Geode processor.16 *17 */···303 err = cs553x_init_one(i, !!(val & FLSH_MEM_IO), val & 0xFFFFFFFF);304 }305306+ /* Register all devices together here. This means we can easily hack it to307 do mtdconcat etc. if we want to. */308 for (i = 0; i < NR_CS553X_CONTROLLERS; i++) {309 if (cs553x_mtd[i]) {
···45 unsigned long size = res->end - res->start + 1;46 int err;4748- info = kmalloc(sizeof(struct onenand_info), GFP_KERNEL);49 if (!info)50 return -ENOMEM;51-52- memset(info, 0, sizeof(struct onenand_info));5354 if (!request_mem_region(res->start, size, dev->driver->name)) {55 err = -EBUSY;···61 }6263 info->onenand.mmcontrol = pdata->mmcontrol;06465 info->mtd.name = pdev->dev.bus_id;66 info->mtd.priv = &info->onenand;
···45 unsigned long size = res->end - res->start + 1;46 int err;4748+ info = kzalloc(sizeof(struct onenand_info), GFP_KERNEL);49 if (!info)50 return -ENOMEM;005152 if (!request_mem_region(res->start, size, dev->driver->name)) {53 err = -EBUSY;···63 }6465 info->onenand.mmcontrol = pdata->mmcontrol;66+ info->onenand.irq = platform_get_irq(pdev, 0);6768 info->mtd.name = pdev->dev.bus_id;69 info->mtd.priv = &info->onenand;
+281-89
drivers/mtd/onenand/onenand_base.c
···13#include <linux/module.h>14#include <linux/init.h>15#include <linux/sched.h>016#include <linux/jiffies.h>17#include <linux/mtd/mtd.h>18#include <linux/mtd/onenand.h>···192 struct onenand_chip *this = mtd->priv;193 int value, readcmd = 0, block_cmd = 0;194 int block, page;195- /* Now we use page size operation */196- int sectors = 4, count = 4;197198 /* Address translation */199 switch (cmd) {···243 }244245 if (page != -1) {00246 int dataram;247248 switch (cmd) {···298 unsigned long timeout;299 unsigned int flags = ONENAND_INT_MASTER;300 unsigned int interrupt = 0;301- unsigned int ctrl, ecc;302303 /* The 20 msec is enough */304 timeout = jiffies + msecs_to_jiffies(20);···310311 if (state != FL_READING)312 cond_resched();313- touch_softlockup_watchdog();314 }315 /* To get correct interrupt status in timeout case */316 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);···317 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);318319 if (ctrl & ONENAND_CTRL_ERROR) {320- /* It maybe occur at initial bad block */321 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n", ctrl);322- /* Clear other interrupt bits for preventing ECC error */323- interrupt &= ONENAND_INT_MASTER;324- }325-326- if (ctrl & ONENAND_CTRL_LOCK) {327- DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error = 0x%04x\n", ctrl);328- return -EACCES;329 }330331 if (interrupt & ONENAND_INT_READ) {332- ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);333- if (ecc & ONENAND_ECC_2BIT_ALL) {334 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: ECC error = 0x%04x\n", ecc);335- return -EBADMSG;0000336 }337 }338339 return 0;000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000340}341342/**···707 size_t *retlen, u_char *buf)708{709 struct onenand_chip *this = mtd->priv;0710 int read = 0, column;711 int thislen;712- int ret = 0;713714 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);715···726727 /* TODO handling oob */728729- while (read < len) {730- thislen = min_t(int, mtd->writesize, len - read);731732- column = from & (mtd->writesize - 1);733- if (column + thislen > mtd->writesize)734- thislen = mtd->writesize - column;735736- if (!onenand_check_bufferram(mtd, from)) {737- this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);000000738739- ret = this->wait(mtd, FL_READING);740- /* First copy data and check return value for ECC handling */741- onenand_update_bufferram(mtd, from, 1);742- }743744- this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);00000000000000000000000000000000000745746- read += thislen;747-748- if (read == len)749- break;750-751- if (ret) {752- DEBUG(MTD_DEBUG_LEVEL0, "onenand_read: read failed = %d\n", ret);753- goto out;754- }755-756- from += thislen;757- buf += thislen;758- }759-760-out:761 /* Deselect and wake up anyone waiting on the device */762 onenand_release_device(mtd);763···790 * retlen == desired len and result == -EBADMSG791 */792 *retlen = read;793- return ret;0000000794}795796/**···834 column = from & (mtd->oobsize - 1);835836 while (read < len) {00837 thislen = mtd->oobsize - column;838 thislen = min_t(int, thislen, len);839···848849 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);85000000851 read += thislen;852853 if (read == len)854 break;855-856- if (ret) {857- DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = %d\n", ret);858- goto out;859- }860861 buf += thislen;862···887{888 BUG_ON(ops->mode != MTD_OOB_PLACE);889890- return onenand_do_read_oob(mtd, from + ops->ooboffs, ops->len,891- &ops->retlen, ops->oobbuf);892}893894#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE···935 void __iomem *dataram0, *dataram1;936 int ret = 0;9370000938 this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);939940 ret = this->wait(mtd, FL_READING);···961#define onenand_verify_oob(...) (0)962#endif963964-#define NOTALIGNED(x) ((x & (mtd->writesize - 1)) != 0)965966/**967 * onenand_write - [MTD Interface] write buffer to FLASH···979 struct onenand_chip *this = mtd->priv;980 int written = 0;981 int ret = 0;0982983 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);984···998 return -EINVAL;999 }10000001001 /* Grab the lock and see if the device is available */1002 onenand_get_device(mtd, FL_WRITING);10031004 /* Loop until all data write */1005 while (written < len) {1006- int thislen = min_t(int, mtd->writesize, len - written);0010071008- this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->writesize);10091010- this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);0000000000001011 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);10121013 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);10141015- onenand_update_bufferram(mtd, to, 1);010161017 ret = this->wait(mtd, FL_WRITING);1018 if (ret) {1019 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: write filaed %d\n", ret);1020- goto out;00000001021 }10221023 written += thislen;10241025- /* Only check verify write turn on */1026- ret = onenand_verify_page(mtd, (u_char *) buf, to);1027- if (ret) {1028- DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: verify failed %d\n", ret);1029- goto out;1030- }1031-1032 if (written == len)1033 break;103401035 to += thislen;1036 buf += thislen;1037 }10381039-out:1040 /* Deselect and wake up anyone waiting on the device */1041 onenand_release_device(mtd);1042···1097 /* Loop until all data write */1098 while (written < len) {1099 int thislen = min_t(int, mtd->oobsize, len - written);0011001101 column = to & (mtd->oobsize - 1);1102···1155{1156 BUG_ON(ops->mode != MTD_OOB_PLACE);11571158- return onenand_do_write_oob(mtd, to + ops->ooboffs, ops->len,1159- &ops->retlen, ops->oobbuf);1160}11611162/**···1227 instr->state = MTD_ERASING;12281229 while (len) {012301231 /* Check if we have a bad block, we do not erase bad blocks */1232 if (onenand_block_checkbad(mtd, addr, 0, 0)) {···1241 ret = this->wait(mtd, FL_ERASING);1242 /* Check, if it is write protected */1243 if (ret) {1244- if (ret == -EPERM)1245- DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Device is write protected!!!\n");1246- else1247- DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift));1248 instr->state = MTD_ERASE_FAILED;1249 instr->fail_addr = addr;1250 goto erase_exit;···1282 /* Release it and go back */1283 onenand_release_device(mtd);1284}1285-12861287/**1288 * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad···1349}13501351/**1352- * onenand_unlock - [MTD Interface] Unlock block(s)1353 * @param mtd MTD device structure1354 * @param ofs offset relative to mtd start1355- * @param len number of bytes to unlock1356 *1357- * Unlock one or more blocks1358 */1359-static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)1360{1361 struct onenand_chip *this = mtd->priv;1362 int start, end, block, value, status;013631364 start = ofs >> this->erase_shift;1365 end = len >> this->erase_shift;0000013661367 /* Continuous lock scheme */1368 if (this->options & ONENAND_HAS_CONT_LOCK) {···1376 this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS);1377 /* Set end block address */1378 this->write_word(start + end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS);1379- /* Write unlock command */1380- this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);13811382 /* There's no return value */1383- this->wait(mtd, FL_UNLOCKING);13841385 /* Sanity check */1386 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)···13891390 /* Check lock status */1391 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);1392- if (!(status & ONENAND_WP_US))1393 printk(KERN_ERR "wp status = 0x%x\n", status);13941395 return 0;···1405 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);1406 /* Set start block address */1407 this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);1408- /* Write unlock command */1409- this->command(mtd, ONENAND_CMD_UNLOCK, 0, 0);14101411 /* There's no return value */1412- this->wait(mtd, FL_UNLOCKING);14131414 /* Sanity check */1415 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)···14181419 /* Check lock status */1420 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);1421- if (!(status & ONENAND_WP_US))1422 printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);1423 }14241425 return 0;000000000000000000000000001426}14271428/**···1495 this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);14961497 /* There's no return value */1498- this->wait(mtd, FL_UNLOCKING);14991500 /* Sanity check */1501 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)···1519 return 0;1520 }15211522- mtd->unlock(mtd, 0x0, this->chipsize);15231524 return 0;1525}···1947 /* Read manufacturer and device IDs from Register */1948 maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);1949 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);1950- ver_id= this->read_word(this->base + ONENAND_REG_VERSION_ID);19511952 /* Check OneNAND device */1953 if (maf_id != bram_maf_id || dev_id != bram_dev_id)···2031 if (!this->command)2032 this->command = onenand_command;2033 if (!this->wait)2034- this->wait = onenand_wait;20352036 if (!this->read_bufferram)2037 this->read_bufferram = onenand_read_bufferram;···2068 init_waitqueue_head(&this->wq);2069 spin_lock_init(&this->chip_lock);20700002071 switch (mtd->oobsize) {2072 case 64:2073 this->ecclayout = &onenand_oob_64;02074 break;20752076 case 32:2077 this->ecclayout = &onenand_oob_32;02078 break;20792080 default:2081 printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",2082 mtd->oobsize);02083 /* To prevent kernel oops */2084 this->ecclayout = &onenand_oob_32;2085 break;2086 }208702088 mtd->ecclayout = this->ecclayout;20892090 /* Fill in remaining MTD driver data */···2114 mtd->lock_user_prot_reg = onenand_lock_user_prot_reg;2115#endif2116 mtd->sync = onenand_sync;2117- mtd->lock = NULL;2118 mtd->unlock = onenand_unlock;2119 mtd->suspend = onenand_suspend;2120 mtd->resume = onenand_resume;
···13#include <linux/module.h>14#include <linux/init.h>15#include <linux/sched.h>16+#include <linux/interrupt.h>17#include <linux/jiffies.h>18#include <linux/mtd/mtd.h>19#include <linux/mtd/onenand.h>···191 struct onenand_chip *this = mtd->priv;192 int value, readcmd = 0, block_cmd = 0;193 int block, page;00194195 /* Address translation */196 switch (cmd) {···244 }245246 if (page != -1) {247+ /* Now we use page size operation */248+ int sectors = 4, count = 4;249 int dataram;250251 switch (cmd) {···297 unsigned long timeout;298 unsigned int flags = ONENAND_INT_MASTER;299 unsigned int interrupt = 0;300+ unsigned int ctrl;301302 /* The 20 msec is enough */303 timeout = jiffies + msecs_to_jiffies(20);···309310 if (state != FL_READING)311 cond_resched();0312 }313 /* To get correct interrupt status in timeout case */314 interrupt = this->read_word(this->base + ONENAND_REG_INTERRUPT);···317 ctrl = this->read_word(this->base + ONENAND_REG_CTRL_STATUS);318319 if (ctrl & ONENAND_CTRL_ERROR) {0320 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: controller error = 0x%04x\n", ctrl);321+ if (ctrl & ONENAND_CTRL_LOCK)322+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: it's locked error.\n");323+ return ctrl;0000324 }325326 if (interrupt & ONENAND_INT_READ) {327+ int ecc = this->read_word(this->base + ONENAND_REG_ECC_STATUS);328+ if (ecc) {329 DEBUG(MTD_DEBUG_LEVEL0, "onenand_wait: ECC error = 0x%04x\n", ecc);330+ if (ecc & ONENAND_ECC_2BIT_ALL) {331+ mtd->ecc_stats.failed++;332+ return ecc;333+ } else if (ecc & ONENAND_ECC_1BIT_ALL)334+ mtd->ecc_stats.corrected++;335 }336 }337338 return 0;339+}340+341+/*342+ * onenand_interrupt - [DEFAULT] onenand interrupt handler343+ * @param irq onenand interrupt number344+ * @param dev_id interrupt data345+ *346+ * complete the work347+ */348+static irqreturn_t onenand_interrupt(int irq, void *data)349+{350+ struct onenand_chip *this = (struct onenand_chip *) data;351+352+ /* To handle shared interrupt */353+ if (!this->complete.done)354+ complete(&this->complete);355+356+ return IRQ_HANDLED;357+}358+359+/*360+ * onenand_interrupt_wait - [DEFAULT] wait until the command is done361+ * @param mtd MTD device structure362+ * @param state state to select the max. timeout value363+ *364+ * Wait for command done.365+ */366+static int onenand_interrupt_wait(struct mtd_info *mtd, int state)367+{368+ struct onenand_chip *this = mtd->priv;369+370+ wait_for_completion(&this->complete);371+372+ return onenand_wait(mtd, state);373+}374+375+/*376+ * onenand_try_interrupt_wait - [DEFAULT] try interrupt wait377+ * @param mtd MTD device structure378+ * @param state state to select the max. timeout value379+ *380+ * Try interrupt based wait (It is used one-time)381+ */382+static int onenand_try_interrupt_wait(struct mtd_info *mtd, int state)383+{384+ struct onenand_chip *this = mtd->priv;385+ unsigned long remain, timeout;386+387+ /* We use interrupt wait first */388+ this->wait = onenand_interrupt_wait;389+390+ timeout = msecs_to_jiffies(100);391+ remain = wait_for_completion_timeout(&this->complete, timeout);392+ if (!remain) {393+ printk(KERN_INFO "OneNAND: There's no interrupt. "394+ "We use the normal wait\n");395+396+ /* Release the irq */397+ free_irq(this->irq, this);398+399+ this->wait = onenand_wait;400+ }401+402+ return onenand_wait(mtd, state);403+}404+405+/*406+ * onenand_setup_wait - [OneNAND Interface] setup onenand wait method407+ * @param mtd MTD device structure408+ *409+ * There's two method to wait onenand work410+ * 1. polling - read interrupt status register411+ * 2. interrupt - use the kernel interrupt method412+ */413+static void onenand_setup_wait(struct mtd_info *mtd)414+{415+ struct onenand_chip *this = mtd->priv;416+ int syscfg;417+418+ init_completion(&this->complete);419+420+ if (this->irq <= 0) {421+ this->wait = onenand_wait;422+ return;423+ }424+425+ if (request_irq(this->irq, &onenand_interrupt,426+ IRQF_SHARED, "onenand", this)) {427+ /* If we can't get irq, use the normal wait */428+ this->wait = onenand_wait;429+ return;430+ }431+432+ /* Enable interrupt */433+ syscfg = this->read_word(this->base + ONENAND_REG_SYS_CFG1);434+ syscfg |= ONENAND_SYS_CFG1_IOBE;435+ this->write_word(syscfg, this->base + ONENAND_REG_SYS_CFG1);436+437+ this->wait = onenand_try_interrupt_wait;438}439440/**···609 size_t *retlen, u_char *buf)610{611 struct onenand_chip *this = mtd->priv;612+ struct mtd_ecc_stats stats;613 int read = 0, column;614 int thislen;615+ int ret = 0, boundary = 0;616617 DEBUG(MTD_DEBUG_LEVEL3, "onenand_read: from = 0x%08x, len = %i\n", (unsigned int) from, (int) len);618···627628 /* TODO handling oob */629630+ stats = mtd->ecc_stats;0631632+ /* Read-while-load method */00633634+ /* Do first load to bufferRAM */635+ if (read < len) {636+ if (!onenand_check_bufferram(mtd, from)) {637+ this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);638+ ret = this->wait(mtd, FL_READING);639+ onenand_update_bufferram(mtd, from, !ret);640+ }641+ }642643+ thislen = min_t(int, mtd->writesize, len - read);644+ column = from & (mtd->writesize - 1);645+ if (column + thislen > mtd->writesize)646+ thislen = mtd->writesize - column;647648+ while (!ret) {649+ /* If there is more to load then start next load */650+ from += thislen;651+ if (read + thislen < len) {652+ this->command(mtd, ONENAND_CMD_READ, from, mtd->writesize);653+ /*654+ * Chip boundary handling in DDP655+ * Now we issued chip 1 read and pointed chip 1656+ * bufferam so we have to point chip 0 bufferam.657+ */658+ if (this->device_id & ONENAND_DEVICE_IS_DDP &&659+ unlikely(from == (this->chipsize >> 1))) {660+ this->write_word(0, this->base + ONENAND_REG_START_ADDRESS2);661+ boundary = 1;662+ } else663+ boundary = 0;664+ ONENAND_SET_PREV_BUFFERRAM(this);665+ }666+ /* While load is going, read from last bufferRAM */667+ this->read_bufferram(mtd, ONENAND_DATARAM, buf, column, thislen);668+ /* See if we are done */669+ read += thislen;670+ if (read == len)671+ break;672+ /* Set up for next read from bufferRAM */673+ if (unlikely(boundary))674+ this->write_word(0x8000, this->base + ONENAND_REG_START_ADDRESS2);675+ ONENAND_SET_NEXT_BUFFERRAM(this);676+ buf += thislen;677+ thislen = min_t(int, mtd->writesize, len - read);678+ column = 0;679+ cond_resched();680+ /* Now wait for load */681+ ret = this->wait(mtd, FL_READING);682+ onenand_update_bufferram(mtd, from, !ret);683+ }684000000000000000685 /* Deselect and wake up anyone waiting on the device */686 onenand_release_device(mtd);687···668 * retlen == desired len and result == -EBADMSG669 */670 *retlen = read;671+672+ if (mtd->ecc_stats.failed - stats.failed)673+ return -EBADMSG;674+675+ if (ret)676+ return ret;677+678+ return mtd->ecc_stats.corrected - stats.corrected ? -EUCLEAN : 0;679}680681/**···705 column = from & (mtd->oobsize - 1);706707 while (read < len) {708+ cond_resched();709+710 thislen = mtd->oobsize - column;711 thislen = min_t(int, thislen, len);712···717718 this->read_bufferram(mtd, ONENAND_SPARERAM, buf, column, thislen);719720+ if (ret) {721+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_read_oob: read failed = 0x%x\n", ret);722+ goto out;723+ }724+725 read += thislen;726727 if (read == len)728 break;00000729730 buf += thislen;731···756{757 BUG_ON(ops->mode != MTD_OOB_PLACE);758759+ return onenand_do_read_oob(mtd, from + ops->ooboffs, ops->ooblen,760+ &ops->oobretlen, ops->oobbuf);761}762763#ifdef CONFIG_MTD_ONENAND_VERIFY_WRITE···804 void __iomem *dataram0, *dataram1;805 int ret = 0;806807+ /* In partial page write, just skip it */808+ if ((addr & (mtd->writesize - 1)) != 0)809+ return 0;810+811 this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);812813 ret = this->wait(mtd, FL_READING);···826#define onenand_verify_oob(...) (0)827#endif828829+#define NOTALIGNED(x) ((x & (this->subpagesize - 1)) != 0)830831/**832 * onenand_write - [MTD Interface] write buffer to FLASH···844 struct onenand_chip *this = mtd->priv;845 int written = 0;846 int ret = 0;847+ int column, subpage;848849 DEBUG(MTD_DEBUG_LEVEL3, "onenand_write: to = 0x%08x, len = %i\n", (unsigned int) to, (int) len);850···862 return -EINVAL;863 }864865+ column = to & (mtd->writesize - 1);866+ subpage = column || (len & (mtd->writesize - 1));867+868 /* Grab the lock and see if the device is available */869 onenand_get_device(mtd, FL_WRITING);870871 /* Loop until all data write */872 while (written < len) {873+ int bytes = mtd->writesize;874+ int thislen = min_t(int, bytes, len - written);875+ u_char *wbuf = (u_char *) buf;876877+ cond_resched();878879+ this->command(mtd, ONENAND_CMD_BUFFERRAM, to, bytes);880+881+ /* Partial page write */882+ if (subpage) {883+ bytes = min_t(int, bytes - column, (int) len);884+ memset(this->page_buf, 0xff, mtd->writesize);885+ memcpy(this->page_buf + column, buf, bytes);886+ wbuf = this->page_buf;887+ /* Even though partial write, we need page size */888+ thislen = mtd->writesize;889+ }890+891+ this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, thislen);892 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);893894 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);895896+ /* In partial page write we don't update bufferram */897+ onenand_update_bufferram(mtd, to, !subpage);898899 ret = this->wait(mtd, FL_WRITING);900 if (ret) {901 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: write filaed %d\n", ret);902+ break;903+ }904+905+ /* Only check verify write turn on */906+ ret = onenand_verify_page(mtd, (u_char *) wbuf, to);907+ if (ret) {908+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: verify failed %d\n", ret);909+ break;910 }911912 written += thislen;9130000000914 if (written == len)915 break;916917+ column = 0;918 to += thislen;919 buf += thislen;920 }9210922 /* Deselect and wake up anyone waiting on the device */923 onenand_release_device(mtd);924···943 /* Loop until all data write */944 while (written < len) {945 int thislen = min_t(int, mtd->oobsize, len - written);946+947+ cond_resched();948949 column = to & (mtd->oobsize - 1);950···999{1000 BUG_ON(ops->mode != MTD_OOB_PLACE);10011002+ return onenand_do_write_oob(mtd, to + ops->ooboffs, ops->ooblen,1003+ &ops->oobretlen, ops->oobbuf);1004}10051006/**···1071 instr->state = MTD_ERASING;10721073 while (len) {1074+ cond_resched();10751076 /* Check if we have a bad block, we do not erase bad blocks */1077 if (onenand_block_checkbad(mtd, addr, 0, 0)) {···1084 ret = this->wait(mtd, FL_ERASING);1085 /* Check, if it is write protected */1086 if (ret) {1087+ DEBUG(MTD_DEBUG_LEVEL0, "onenand_erase: Failed erase, block %d\n", (unsigned) (addr >> this->erase_shift));0001088 instr->state = MTD_ERASE_FAILED;1089 instr->fail_addr = addr;1090 goto erase_exit;···1128 /* Release it and go back */1129 onenand_release_device(mtd);1130}011311132/**1133 * onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad···1196}11971198/**1199+ * onenand_do_lock_cmd - [OneNAND Interface] Lock or unlock block(s)1200 * @param mtd MTD device structure1201 * @param ofs offset relative to mtd start1202+ * @param len number of bytes to lock or unlock1203 *1204+ * Lock or unlock one or more blocks1205 */1206+static int onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int cmd)1207{1208 struct onenand_chip *this = mtd->priv;1209 int start, end, block, value, status;1210+ int wp_status_mask;12111212 start = ofs >> this->erase_shift;1213 end = len >> this->erase_shift;1214+1215+ if (cmd == ONENAND_CMD_LOCK)1216+ wp_status_mask = ONENAND_WP_LS;1217+ else1218+ wp_status_mask = ONENAND_WP_US;12191220 /* Continuous lock scheme */1221 if (this->options & ONENAND_HAS_CONT_LOCK) {···1217 this->write_word(start, this->base + ONENAND_REG_START_BLOCK_ADDRESS);1218 /* Set end block address */1219 this->write_word(start + end - 1, this->base + ONENAND_REG_END_BLOCK_ADDRESS);1220+ /* Write lock command */1221+ this->command(mtd, cmd, 0, 0);12221223 /* There's no return value */1224+ this->wait(mtd, FL_LOCKING);12251226 /* Sanity check */1227 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)···12301231 /* Check lock status */1232 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);1233+ if (!(status & wp_status_mask))1234 printk(KERN_ERR "wp status = 0x%x\n", status);12351236 return 0;···1246 this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2);1247 /* Set start block address */1248 this->write_word(block, this->base + ONENAND_REG_START_BLOCK_ADDRESS);1249+ /* Write lock command */1250+ this->command(mtd, cmd, 0, 0);12511252 /* There's no return value */1253+ this->wait(mtd, FL_LOCKING);12541255 /* Sanity check */1256 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)···12591260 /* Check lock status */1261 status = this->read_word(this->base + ONENAND_REG_WP_STATUS);1262+ if (!(status & wp_status_mask))1263 printk(KERN_ERR "block = %d, wp status = 0x%x\n", block, status);1264 }12651266 return 0;1267+}1268+1269+/**1270+ * onenand_lock - [MTD Interface] Lock block(s)1271+ * @param mtd MTD device structure1272+ * @param ofs offset relative to mtd start1273+ * @param len number of bytes to unlock1274+ *1275+ * Lock one or more blocks1276+ */1277+static int onenand_lock(struct mtd_info *mtd, loff_t ofs, size_t len)1278+{1279+ return onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_LOCK);1280+}1281+1282+/**1283+ * onenand_unlock - [MTD Interface] Unlock block(s)1284+ * @param mtd MTD device structure1285+ * @param ofs offset relative to mtd start1286+ * @param len number of bytes to unlock1287+ *1288+ * Unlock one or more blocks1289+ */1290+static int onenand_unlock(struct mtd_info *mtd, loff_t ofs, size_t len)1291+{1292+ return onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);1293}12941295/**···1310 this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);13111312 /* There's no return value */1313+ this->wait(mtd, FL_LOCKING);13141315 /* Sanity check */1316 while (this->read_word(this->base + ONENAND_REG_CTRL_STATUS)···1334 return 0;1335 }13361337+ onenand_unlock(mtd, 0x0, this->chipsize);13381339 return 0;1340}···1762 /* Read manufacturer and device IDs from Register */1763 maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);1764 dev_id = this->read_word(this->base + ONENAND_REG_DEVICE_ID);1765+ ver_id = this->read_word(this->base + ONENAND_REG_VERSION_ID);17661767 /* Check OneNAND device */1768 if (maf_id != bram_maf_id || dev_id != bram_dev_id)···1846 if (!this->command)1847 this->command = onenand_command;1848 if (!this->wait)1849+ onenand_setup_wait(mtd);18501851 if (!this->read_bufferram)1852 this->read_bufferram = onenand_read_bufferram;···1883 init_waitqueue_head(&this->wq);1884 spin_lock_init(&this->chip_lock);18851886+ /*1887+ * Allow subpage writes up to oobsize.1888+ */1889 switch (mtd->oobsize) {1890 case 64:1891 this->ecclayout = &onenand_oob_64;1892+ mtd->subpage_sft = 2;1893 break;18941895 case 32:1896 this->ecclayout = &onenand_oob_32;1897+ mtd->subpage_sft = 1;1898 break;18991900 default:1901 printk(KERN_WARNING "No OOB scheme defined for oobsize %d\n",1902 mtd->oobsize);1903+ mtd->subpage_sft = 0;1904 /* To prevent kernel oops */1905 this->ecclayout = &onenand_oob_32;1906 break;1907 }19081909+ this->subpagesize = mtd->writesize >> mtd->subpage_sft;1910 mtd->ecclayout = this->ecclayout;19111912 /* Fill in remaining MTD driver data */···1922 mtd->lock_user_prot_reg = onenand_lock_user_prot_reg;1923#endif1924 mtd->sync = onenand_sync;1925+ mtd->lock = onenand_lock;1926 mtd->unlock = onenand_unlock;1927 mtd->suspend = onenand_suspend;1928 mtd->resume = onenand_resume;
+6-8
drivers/mtd/onenand/onenand_bbt.c
···93 ret = onenand_do_read_oob(mtd, from + j * mtd->writesize + bd->offs,94 readlen, &retlen, &buf[0]);9596- if (ret)097 return ret;9899 if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) {100 bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);101 printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",102 i >> 1, (unsigned int) from);0103 break;104 }105 }···179 int len, ret = 0;180181 len = mtd->size >> (this->erase_shift + 2);182- /* Allocate memory (2bit per block) */183- bbm->bbt = kmalloc(len, GFP_KERNEL);184 if (!bbm->bbt) {185 printk(KERN_ERR "onenand_scan_bbt: Out of memory\n");186 return -ENOMEM;187 }188- /* Clear the memory bad block table */189- memset(bbm->bbt, 0x00, len);190191 /* Set the bad block position */192 bbm->badblockpos = ONENAND_BADBLOCK_POS;···230 struct onenand_chip *this = mtd->priv;231 struct bbm_info *bbm;232233- this->bbm = kmalloc(sizeof(struct bbm_info), GFP_KERNEL);234 if (!this->bbm)235 return -ENOMEM;236237 bbm = this->bbm;238-239- memset(bbm, 0, sizeof(struct bbm_info));240241 /* 1KB page has same configuration as 2KB page */242 if (!bbm->badblock_pattern)
···93 ret = onenand_do_read_oob(mtd, from + j * mtd->writesize + bd->offs,94 readlen, &retlen, &buf[0]);9596+ /* If it is a initial bad block, just ignore it */97+ if (ret && !(ret & ONENAND_CTRL_LOAD))98 return ret;99100 if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) {101 bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);102 printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",103 i >> 1, (unsigned int) from);104+ mtd->ecc_stats.badblocks++;105 break;106 }107 }···177 int len, ret = 0;178179 len = mtd->size >> (this->erase_shift + 2);180+ /* Allocate memory (2bit per block) and clear the memory bad block table */181+ bbm->bbt = kzalloc(len, GFP_KERNEL);182 if (!bbm->bbt) {183 printk(KERN_ERR "onenand_scan_bbt: Out of memory\n");184 return -ENOMEM;185 }00186187 /* Set the bad block position */188 bbm->badblockpos = ONENAND_BADBLOCK_POS;···230 struct onenand_chip *this = mtd->priv;231 struct bbm_info *bbm;232233+ this->bbm = kzalloc(sizeof(struct bbm_info), GFP_KERNEL);234 if (!this->bbm)235 return -ENOMEM;236237 bbm = this->bbm;00238239 /* 1KB page has same configuration as 2KB page */240 if (!bbm->badblock_pattern)
+24-6
drivers/mtd/redboot.c
···96 */97 if (swab32(buf[i].size) == master->erasesize) {98 int j;99- for (j = 0; j < numslots && buf[j].name[0] != 0xff; ++j) {000000000000100 /* The unsigned long fields were written with the101 * wrong byte sex, name and pad have no byte sex.102 */···122 }123 }124 break;000125 }126 }127 if (i == numslots) {···138 for (i = 0; i < numslots; i++) {139 struct fis_list *new_fl, **prev;140141- if (buf[i].name[0] == 0xff)142- continue;00000143 if (!redboot_checksum(&buf[i]))144 break;145···185 }186 }187#endif188- parts = kmalloc(sizeof(*parts)*nrparts + nulllen + namelen, GFP_KERNEL);189190 if (!parts) {191 ret = -ENOMEM;192 goto out;193 }194-195- memset(parts, 0, sizeof(*parts)*nrparts + nulllen + namelen);196197 nullname = (char *)&parts[nrparts];198#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
···96 */97 if (swab32(buf[i].size) == master->erasesize) {98 int j;99+ for (j = 0; j < numslots; ++j) {100+101+ /* A single 0xff denotes a deleted entry.102+ * Two of them in a row is the end of the table.103+ */104+ if (buf[j].name[0] == 0xff) {105+ if (buf[j].name[1] == 0xff) {106+ break;107+ } else {108+ continue;109+ }110+ }111+112 /* The unsigned long fields were written with the113 * wrong byte sex, name and pad have no byte sex.114 */···110 }111 }112 break;113+ } else {114+ /* re-calculate of real numslots */115+ numslots = buf[i].size / sizeof(struct fis_image_desc);116 }117 }118 if (i == numslots) {···123 for (i = 0; i < numslots; i++) {124 struct fis_list *new_fl, **prev;125126+ if (buf[i].name[0] == 0xff) {127+ if (buf[i].name[1] == 0xff) {128+ break;129+ } else {130+ continue;131+ }132+ }133 if (!redboot_checksum(&buf[i]))134 break;135···165 }166 }167#endif168+ parts = kzalloc(sizeof(*parts)*nrparts + nulllen + namelen, GFP_KERNEL);169170 if (!parts) {171 ret = -ENOMEM;172 goto out;173 }00174175 nullname = (char *)&parts[nrparts];176#ifdef CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED
···150}151152/**153- * pci_match_device - Tell if a PCI device structure has a matching154- * PCI device id structure155 * @drv: the PCI driver to match against156 * @dev: the PCI device structure to match against157 *
···150}151152/**153+ * pci_match_device - Tell if a PCI device structure has a matching PCI device id structure0154 * @drv: the PCI driver to match against155 * @dev: the PCI device structure to match against156 *
+5
drivers/pci/quirks.c
···1002 case 0x186a: /* M6Ne notebook */1003 asus_hides_smbus = 1;1004 }000001005 if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) {1006 switch (dev->subsystem_device) {1007 case 0x1882: /* M6V notebook */
···1002 case 0x186a: /* M6Ne notebook */1003 asus_hides_smbus = 1;1004 }1005+ if (dev->device == PCI_DEVICE_ID_INTEL_82865_HB)1006+ switch (dev->subsystem_device) {1007+ case 0x80f2: /* P4P800-X */1008+ asus_hides_smbus = 1;1009+ }1010 if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB) {1011 switch (dev->subsystem_device) {1012 case 0x1882: /* M6V notebook */
···7273 If you are unsure about this, say N here.7475-config USB_MULTITHREAD_PROBE76- bool "USB Multi-threaded probe (EXPERIMENTAL)"77- depends on USB && EXPERIMENTAL78- default n79- help80- Say Y here if you want the USB core to spawn a new thread for81- every USB device that is probed. This can cause a small speedup82- in boot times on systems with a lot of different USB devices.83-84- This option should be safe to enable, but if any odd probing85- problems are found, please disable it, or dynamically turn it86- off in the /sys/module/usbcore/parameters/multithread_probe87- file88-89- When in doubt, say N.90-91config USB_OTG92 bool93 depends on USB && EXPERIMENTAL
···7273 If you are unsure about this, say N here.74000000000000000075config USB_OTG76 bool77 depends on USB && EXPERIMENTAL
+1-8
drivers/usb/core/hub.c
···88static struct task_struct *khubd_task;8990/* multithreaded probe logic */91-static int multithread_probe =92-#ifdef CONFIG_USB_MULTITHREAD_PROBE93- 1;94-#else95- 0;96-#endif97-module_param(multithread_probe, bool, S_IRUGO);98-MODULE_PARM_DESC(multithread_probe, "Run each USB device probe in a new thread");99100/* cycle leds on hubs that aren't blinking for attention */101static int blinkenlights = 0;
···88static struct task_struct *khubd_task;8990/* multithreaded probe logic */91+static int multithread_probe = 0;00000009293/* cycle leds on hubs that aren't blinking for attention */94static int blinkenlights = 0;
···197 US_SC_DEVICE, US_PR_DEVICE, NULL,198 US_FL_MAX_SECTORS_64 ),1990000000200/* Reported by Alex Corcoles <alex@corcoles.net> */201UNUSUAL_DEV( 0x0421, 0x0495, 0x0370, 0x0370,202 "Nokia",···260 "Rio Karma",261 US_SC_SCSI, US_PR_KARMA, rio_karma_init, 0),262#endif000000000000263264/* Patch submitted by Philipp Friedrich <philipp@void.at> */265UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100,
···197 US_SC_DEVICE, US_PR_DEVICE, NULL,198 US_FL_MAX_SECTORS_64 ),199200+/* Reported by Manuel Osdoba <manuel.osdoba@tu-ilmenau.de> */201+UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x0452,202+ "Nokia",203+ "Nokia 6233",204+ US_SC_DEVICE, US_PR_DEVICE, NULL,205+ US_FL_MAX_SECTORS_64 ),206+207/* Reported by Alex Corcoles <alex@corcoles.net> */208UNUSUAL_DEV( 0x0421, 0x0495, 0x0370, 0x0370,209 "Nokia",···253 "Rio Karma",254 US_SC_SCSI, US_PR_KARMA, rio_karma_init, 0),255#endif256+257+/*258+ * This virtual floppy is found in Sun equipment (x4600, x4200m2, etc.)259+ * Reported by Pete Zaitcev <zaitcev@redhat.com>260+ * This device chokes on both version of MODE SENSE which we have, so261+ * use_10_for_ms is not effective, and we use US_FL_NO_WP_DETECT.262+ */263+UNUSUAL_DEV( 0x046b, 0xff40, 0x0100, 0x0100,264+ "AMI",265+ "Virtual Floppy",266+ US_SC_DEVICE, US_PR_DEVICE, NULL,267+ US_FL_NO_WP_DETECT),268269/* Patch submitted by Philipp Friedrich <philipp@void.at> */270UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100,
+9-1
fs/block_dev.c
···146 iocb->ki_nbytes = -EIO;147148 if (atomic_dec_and_test(bio_count)) {149- if (iocb->ki_nbytes < 0)150 aio_complete(iocb, iocb->ki_nbytes, 0);151 else152 aio_complete(iocb, iocb->ki_left, 0);···188 pvec->idx = 0;189 }190 return pvec->page[pvec->idx++];000000191}192193static ssize_t···284 count = min(count, nbytes);285 goto same_bio;286 }00287 }288289 /* bio is ready, submit it */
···146 iocb->ki_nbytes = -EIO;147148 if (atomic_dec_and_test(bio_count)) {149+ if ((long)iocb->ki_nbytes < 0)150 aio_complete(iocb, iocb->ki_nbytes, 0);151 else152 aio_complete(iocb, iocb->ki_left, 0);···188 pvec->idx = 0;189 }190 return pvec->page[pvec->idx++];191+}192+193+/* return a page back to pvec array */194+static void blk_unget_page(struct page *page, struct pvec *pvec)195+{196+ pvec->page[--pvec->idx] = page;197}198199static ssize_t···278 count = min(count, nbytes);279 goto same_bio;280 }281+ } else {282+ blk_unget_page(page, &pvec);283 }284285 /* bio is ready, submit it */
···502 if (ret)503 return ret;504505- c->inocache_list = kmalloc(INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *), GFP_KERNEL);506 if (!c->inocache_list) {507 ret = -ENOMEM;508 goto out_wbuf;509 }510- memset(c->inocache_list, 0, INOCACHE_HASHSIZE * sizeof(struct jffs2_inode_cache *));511512 jffs2_init_xattr_subsystem(c);513
···502 if (ret)503 return ret;504505+ c->inocache_list = kcalloc(INOCACHE_HASHSIZE, sizeof(struct jffs2_inode_cache *), GFP_KERNEL);506 if (!c->inocache_list) {507 ret = -ENOMEM;508 goto out_wbuf;509 }0510511 jffs2_init_xattr_subsystem(c);512
+2
fs/jffs2/gc.c
···838839 for (raw = f->inocache->nodes; raw != (void *)f->inocache; raw = raw->next_in_ino) {84000841 /* We only care about obsolete ones */842 if (!(ref_obsolete(raw)))843 continue;
···838839 for (raw = f->inocache->nodes; raw != (void *)f->inocache; raw = raw->next_in_ino) {840841+ cond_resched();842+843 /* We only care about obsolete ones */844 if (!(ref_obsolete(raw)))845 continue;
···51 */5253 if (!p) {54- printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n");55 p = ERR_PTR(-EIO);56 }57 D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->target));
···51 */5253 if (!p) {54+ printk(KERN_ERR "jffs2_follow_link(): can't find symlink target\n");55 p = ERR_PTR(-EIO);56 }57 D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->target));
+9-12
fs/jffs2/wbuf.c
···969 int oobsize = c->mtd->oobsize;970 struct mtd_oob_ops ops;971972- ops.len = NR_OOB_SCAN_PAGES * oobsize;973- ops.ooblen = oobsize;974 ops.oobbuf = c->oobbuf;975 ops.ooboffs = 0;976 ops.datbuf = NULL;···982 return ret;983 }984985- if (ops.retlen < ops.len) {986 D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB "987 "returned short read (%zd bytes not %d) for block "988- "at %08x\n", ops.retlen, ops.len, jeb->offset));989 return -EIO;990 }991···1004 }10051006 /* we know, we are aligned :) */1007- for (page = oobsize; page < ops.len; page += sizeof(long)) {1008 long dat = *(long *)(&ops.oobbuf[page]);1009 if(dat != -1)1010 return 1;···1032 return 2;1033 }10341035- ops.len = oobsize;1036 ops.ooblen = oobsize;1037 ops.oobbuf = c->oobbuf;1038 ops.ooboffs = 0;···1046 return ret;1047 }10481049- if (ops.retlen < ops.len) {1050 D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): "1051 "Read OOB return short read (%zd bytes not %d) "1052- "for block at %08x\n", ops.retlen, ops.len,1053 jeb->offset));1054 return -EIO;1055 }···1088 n.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);1089 n.totlen = cpu_to_je32(8);10901091- ops.len = c->fsdata_len;1092- ops.ooblen = c->fsdata_len;;1093 ops.oobbuf = (uint8_t *)&n;1094 ops.ooboffs = c->fsdata_pos;1095 ops.datbuf = NULL;···1102 jeb->offset, ret));1103 return ret;1104 }1105- if (ops.retlen != ops.len) {1106 D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): "1107 "Short write for block at %08x: %zd not %d\n",1108- jeb->offset, ops.retlen, ops.len));1109 return -EIO;1110 }1111 return 0;
···969 int oobsize = c->mtd->oobsize;970 struct mtd_oob_ops ops;971972+ ops.ooblen = NR_OOB_SCAN_PAGES * oobsize;0973 ops.oobbuf = c->oobbuf;974 ops.ooboffs = 0;975 ops.datbuf = NULL;···983 return ret;984 }985986+ if (ops.oobretlen < ops.ooblen) {987 D1(printk(KERN_WARNING "jffs2_check_oob_empty(): Read OOB "988 "returned short read (%zd bytes not %d) for block "989+ "at %08x\n", ops.oobretlen, ops.ooblen, jeb->offset));990 return -EIO;991 }992···1005 }10061007 /* we know, we are aligned :) */1008+ for (page = oobsize; page < ops.ooblen; page += sizeof(long)) {1009 long dat = *(long *)(&ops.oobbuf[page]);1010 if(dat != -1)1011 return 1;···1033 return 2;1034 }103501036 ops.ooblen = oobsize;1037 ops.oobbuf = c->oobbuf;1038 ops.ooboffs = 0;···1048 return ret;1049 }10501051+ if (ops.oobretlen < ops.ooblen) {1052 D1 (printk (KERN_WARNING "jffs2_check_nand_cleanmarker(): "1053 "Read OOB return short read (%zd bytes not %d) "1054+ "for block at %08x\n", ops.oobretlen, ops.ooblen,1055 jeb->offset));1056 return -EIO;1057 }···1090 n.nodetype = cpu_to_je16(JFFS2_NODETYPE_CLEANMARKER);1091 n.totlen = cpu_to_je32(8);10921093+ ops.ooblen = c->fsdata_len;01094 ops.oobbuf = (uint8_t *)&n;1095 ops.ooboffs = c->fsdata_pos;1096 ops.datbuf = NULL;···1105 jeb->offset, ret));1106 return ret;1107 }1108+ if (ops.oobretlen != ops.ooblen) {1109 D1(printk(KERN_WARNING "jffs2_write_nand_cleanmarker(): "1110 "Short write for block at %08x: %zd not %d\n",1111+ jeb->offset, ops.oobretlen, ops.ooblen));1112 return -EIO;1113 }1114 return 0;
+2-3
fs/jffs2/xattr.c
···399{400 /* must be called under down_write(xattr_sem) */401 if (atomic_dec_and_lock(&xd->refcnt, &c->erase_completion_lock)) {402- uint32_t xid = xd->xid, version = xd->version;403-404 unload_xattr_datum(c, xd);405 xd->flags |= JFFS2_XFLAGS_DEAD;406 if (xd->node == (void *)xd) {···409 }410 spin_unlock(&c->erase_completion_lock);411412- dbg_xattr("xdatum(xid=%u, version=%u) was removed.\n", xid, version);0413 }414}415
···399{400 /* must be called under down_write(xattr_sem) */401 if (atomic_dec_and_lock(&xd->refcnt, &c->erase_completion_lock)) {00402 unload_xattr_datum(c, xd);403 xd->flags |= JFFS2_XFLAGS_DEAD;404 if (xd->node == (void *)xd) {···411 }412 spin_unlock(&c->erase_completion_lock);413414+ dbg_xattr("xdatum(xid=%u, version=%u) was removed.\n",415+ xd->xid, xd->version);416 }417}418
···24 struct mtd_info *mtd;25 struct mutex lock;26 int devnum;27- int blksize;28 unsigned long size;29 int readonly;30 void *blkcore_priv; /* gendisk in 2.5, devfs_handle in 2.4 */···35 char *name;36 int major;37 int part_bits;003839 /* Access functions */40 int (*readsect)(struct mtd_blktrans_dev *dev,
···24 struct mtd_info *mtd;25 struct mutex lock;26 int devnum;027 unsigned long size;28 int readonly;29 void *blkcore_priv; /* gendisk in 2.5, devfs_handle in 2.4 */···36 char *name;37 int major;38 int part_bits;39+ int blksize;40+ int blkshift;4142 /* Access functions */43 int (*readsect)(struct mtd_blktrans_dev *dev,
+16-8
include/linux/mtd/mtd.h
···2324#define MTD_CHAR_MAJOR 9025#define MTD_BLOCK_MAJOR 3126-#define MAX_MTD_DEVICES 162728#define MTD_ERASE_PENDING 0x0129#define MTD_ERASING 0x02···75 * struct mtd_oob_ops - oob operation operands76 * @mode: operation mode77 *78- * @len: number of bytes to write/read. When a data buffer is given79- * (datbuf != NULL) this is the number of data bytes. When80- * no data buffer is available this is the number of oob bytes.81 *82- * @retlen: number of bytes written/read. When a data buffer is given83- * (datbuf != NULL) this is the number of data bytes. When84- * no data buffer is available this is the number of oob bytes.85 *86- * @ooblen: number of oob bytes per page087 * @ooboffs: offset of oob data in the oob area (only relevant when88 * mode = MTD_OOB_PLACE)89 * @datbuf: data buffer - if NULL only oob data are read/written···91 size_t len;92 size_t retlen;93 size_t ooblen;094 uint32_t ooboffs;95 uint8_t *datbuf;96 uint8_t *oobbuf;···200201 /* ECC status information */202 struct mtd_ecc_stats ecc_stats;00203204 void *priv;205206 struct module *owner;207 int usecount;0000000208};209210···223extern int del_mtd_device (struct mtd_info *mtd);224225extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);0226227extern void put_mtd_device(struct mtd_info *mtd);228
···2324#define MTD_CHAR_MAJOR 9025#define MTD_BLOCK_MAJOR 3126+#define MAX_MTD_DEVICES 322728#define MTD_ERASE_PENDING 0x0129#define MTD_ERASING 0x02···75 * struct mtd_oob_ops - oob operation operands76 * @mode: operation mode77 *78+ * @len: number of data bytes to write/read0079 *80+ * @retlen: number of data bytes written/read0081 *82+ * @ooblen: number of oob bytes to write/read83+ * @oobretlen: number of oob bytes written/read84 * @ooboffs: offset of oob data in the oob area (only relevant when85 * mode = MTD_OOB_PLACE)86 * @datbuf: data buffer - if NULL only oob data are read/written···94 size_t len;95 size_t retlen;96 size_t ooblen;97+ size_t oobretlen;98 uint32_t ooboffs;99 uint8_t *datbuf;100 uint8_t *oobbuf;···202203 /* ECC status information */204 struct mtd_ecc_stats ecc_stats;205+ /* Subpage shift (NAND) */206+ int subpage_sft;207208 void *priv;209210 struct module *owner;211 int usecount;212+213+ /* If the driver is something smart, like UBI, it may need to maintain214+ * its own reference counting. The below functions are only for driver.215+ * The driver may register its callbacks. These callbacks are not216+ * supposed to be called by MTD users */217+ int (*get_device) (struct mtd_info *mtd);218+ void (*put_device) (struct mtd_info *mtd);219};220221···216extern int del_mtd_device (struct mtd_info *mtd);217218extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);219+extern struct mtd_info *get_mtd_device_nm(const char *name);220221extern void put_mtd_device(struct mtd_info *mtd);222
+10-5
include/linux/mtd/nand.h
···166 * for all large page devices, as they do not support167 * autoincrement.*/168#define NAND_NO_READRDY 0x00000100000169170/* Options valid for Samsung large page devices */171#define NAND_SAMSUNG_LP_OPTIONS \···196/* Nand scan has allocated controller struct */197#define NAND_CONTROLLER_ALLOC 0x80000000198000199200/*201 * nand_state_t - chip states···292 * struct nand_buffers - buffer structure for read/write293 * @ecccalc: buffer for calculated ecc294 * @ecccode: buffer for ecc read from flash295- * @oobwbuf: buffer for write oob data296 * @databuf: buffer for data - dynamically sized297- * @oobrbuf: buffer to read oob data298 *299 * Do not change the order of buffers. databuf and oobrbuf must be in300 * consecutive order.···300struct nand_buffers {301 uint8_t ecccalc[NAND_MAX_OOBSIZE];302 uint8_t ecccode[NAND_MAX_OOBSIZE];303- uint8_t oobwbuf[NAND_MAX_OOBSIZE];304- uint8_t databuf[NAND_MAX_PAGESIZE];305- uint8_t oobrbuf[NAND_MAX_OOBSIZE];306};307308/**···347 * @chipsize: [INTERN] the size of one chip for multichip arrays348 * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1349 * @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf0350 * @ecclayout: [REPLACEABLE] the default ecc placement scheme351 * @bbt: [INTERN] bad block table pointer352 * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup···395 unsigned long chipsize;396 int pagemask;397 int pagebuf;00398 int badblockpos;399400 nand_state_t state;
···166 * for all large page devices, as they do not support167 * autoincrement.*/168#define NAND_NO_READRDY 0x00000100169+/* Chip does not allow subpage writes */170+#define NAND_NO_SUBPAGE_WRITE 0x00000200171+172173/* Options valid for Samsung large page devices */174#define NAND_SAMSUNG_LP_OPTIONS \···193/* Nand scan has allocated controller struct */194#define NAND_CONTROLLER_ALLOC 0x80000000195196+/* Cell info constants */197+#define NAND_CI_CHIPNR_MSK 0x03198+#define NAND_CI_CELLTYPE_MSK 0x0C199200/*201 * nand_state_t - chip states···286 * struct nand_buffers - buffer structure for read/write287 * @ecccalc: buffer for calculated ecc288 * @ecccode: buffer for ecc read from flash0289 * @databuf: buffer for data - dynamically sized0290 *291 * Do not change the order of buffers. databuf and oobrbuf must be in292 * consecutive order.···296struct nand_buffers {297 uint8_t ecccalc[NAND_MAX_OOBSIZE];298 uint8_t ecccode[NAND_MAX_OOBSIZE];299+ uint8_t databuf[NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE];00300};301302/**···345 * @chipsize: [INTERN] the size of one chip for multichip arrays346 * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1347 * @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf348+ * @subpagesize: [INTERN] holds the subpagesize349 * @ecclayout: [REPLACEABLE] the default ecc placement scheme350 * @bbt: [INTERN] bad block table pointer351 * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup···392 unsigned long chipsize;393 int pagemask;394 int pagebuf;395+ int subpagesize;396+ uint8_t cellinfo;397 int badblockpos;398399 nand_state_t state;
+7-1
include/linux/mtd/onenand.h
···13#define __LINUX_MTD_ONENAND_H1415#include <linux/spinlock.h>016#include <linux/mtd/onenand_regs.h>17#include <linux/mtd/bbm.h>18···34 FL_WRITING,35 FL_ERASING,36 FL_SYNCING,37- FL_UNLOCKING,38 FL_LOCKING,39 FL_RESETING,40 FL_OTPING,···88 * operation is in progress89 * @state: [INTERN] the current state of the OneNAND device90 * @page_buf: data buffer091 * @ecclayout: [REPLACEABLE] the default ecc placement scheme92 * @bbm: [REPLACEABLE] pointer to Bad Block Management93 * @priv: [OPTIONAL] pointer to private chip date···121 int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);122 int (*scan_bbt)(struct mtd_info *mtd);123000124 spinlock_t chip_lock;125 wait_queue_head_t wq;126 onenand_state_t state;127 unsigned char *page_buf;1280129 struct nand_ecclayout *ecclayout;130131 void *bbm;···143#define ONENAND_CURRENT_BUFFERRAM(this) (this->bufferram_index)144#define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1)145#define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1)0146147#define ONENAND_GET_SYS_CFG1(this) \148 (this->read_word(this->base + ONENAND_REG_SYS_CFG1))
···13#define __LINUX_MTD_ONENAND_H1415#include <linux/spinlock.h>16+#include <linux/completion.h>17#include <linux/mtd/onenand_regs.h>18#include <linux/mtd/bbm.h>19···33 FL_WRITING,34 FL_ERASING,35 FL_SYNCING,036 FL_LOCKING,37 FL_RESETING,38 FL_OTPING,···88 * operation is in progress89 * @state: [INTERN] the current state of the OneNAND device90 * @page_buf: data buffer91+ * @subpagesize: [INTERN] holds the subpagesize92 * @ecclayout: [REPLACEABLE] the default ecc placement scheme93 * @bbm: [REPLACEABLE] pointer to Bad Block Management94 * @priv: [OPTIONAL] pointer to private chip date···120 int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);121 int (*scan_bbt)(struct mtd_info *mtd);122123+ struct completion complete;124+ int irq;125+126 spinlock_t chip_lock;127 wait_queue_head_t wq;128 onenand_state_t state;129 unsigned char *page_buf;130131+ int subpagesize;132 struct nand_ecclayout *ecclayout;133134 void *bbm;···138#define ONENAND_CURRENT_BUFFERRAM(this) (this->bufferram_index)139#define ONENAND_NEXT_BUFFERRAM(this) (this->bufferram_index ^ 1)140#define ONENAND_SET_NEXT_BUFFERRAM(this) (this->bufferram_index ^= 1)141+#define ONENAND_SET_PREV_BUFFERRAM(this) (this->bufferram_index ^= 1)142143#define ONENAND_GET_SYS_CFG1(this) \144 (this->read_word(this->base + ONENAND_REG_SYS_CFG1))
···1011#include <linux/types.h>12#include <linux/ioctl.h>13-#include <linux/qic117.h>1415/*16 * Structures and definitions for mag tape io control commands···115#define MT_ISFTAPE_UNKNOWN 0x800000 /* obsolete */116#define MT_ISFTAPE_FLAG 0x800000117118-struct mt_tape_info {119- long t_type; /* device type id (mt_type) */120- char *t_name; /* descriptive name */121-};122-123-#define MT_TAPE_INFO { \124- {MT_ISUNKNOWN, "Unknown type of tape device"}, \125- {MT_ISQIC02, "Generic QIC-02 tape streamer"}, \126- {MT_ISWT5150, "Wangtek 5150, QIC-150"}, \127- {MT_ISARCHIVE_5945L2, "Archive 5945L-2"}, \128- {MT_ISCMSJ500, "CMS Jumbo 500"}, \129- {MT_ISTDC3610, "Tandberg TDC 3610, QIC-24"}, \130- {MT_ISARCHIVE_VP60I, "Archive VP60i, QIC-02"}, \131- {MT_ISARCHIVE_2150L, "Archive Viper 2150L"}, \132- {MT_ISARCHIVE_2060L, "Archive Viper 2060L"}, \133- {MT_ISARCHIVESC499, "Archive SC-499 QIC-36 controller"}, \134- {MT_ISQIC02_ALL_FEATURES, "Generic QIC-02 tape, all features"}, \135- {MT_ISWT5099EEN24, "Wangtek 5099-een24, 60MB"}, \136- {MT_ISTEAC_MT2ST, "Teac MT-2ST 155mb data cassette drive"}, \137- {MT_ISEVEREX_FT40A, "Everex FT40A, QIC-40"}, \138- {MT_ISONSTREAM_SC, "OnStream SC-, DI-, DP-, or USB tape drive"}, \139- {MT_ISSCSI1, "Generic SCSI-1 tape"}, \140- {MT_ISSCSI2, "Generic SCSI-2 tape"}, \141- {0, NULL} \142-}143-144145/* structure for MTIOCPOS - mag tape get position command */146···123};124125126-/* structure for MTIOCVOLINFO, query information about the volume127- * currently positioned at (zftape)128- */129-struct mtvolinfo {130- unsigned int mt_volno; /* vol-number */131- unsigned int mt_blksz; /* blocksize used when recording */132- unsigned int mt_rawsize; /* raw tape space consumed, in kb */133- unsigned int mt_size; /* volume size after decompression, in kb */134- unsigned int mt_cmpr:1; /* this volume has been compressed */135-};136-137-/* raw access to a floppy drive, read and write an arbitrary segment.138- * For ftape/zftape to support formatting etc.139- */140-#define MT_FT_RD_SINGLE 0141-#define MT_FT_RD_AHEAD 1142-#define MT_FT_WR_ASYNC 0 /* start tape only when all buffers are full */143-#define MT_FT_WR_MULTI 1 /* start tape, continue until buffers are empty */144-#define MT_FT_WR_SINGLE 2 /* write a single segment and stop afterwards */145-#define MT_FT_WR_DELETE 3 /* write deleted data marks, one segment at time */146-147-struct mtftseg148-{ 149- unsigned mt_segno; /* the segment to read or write */150- unsigned mt_mode; /* modes for read/write (sync/async etc.) */151- int mt_result; /* result of r/w request, not of the ioctl */152- void __user *mt_data; /* User space buffer: must be 29kb */153-};154-155-/* get tape capacity (ftape/zftape)156- */157-struct mttapesize {158- unsigned long mt_capacity; /* entire, uncompressed capacity 159- * of a cartridge160- */161- unsigned long mt_used; /* what has been used so far, raw 162- * uncompressed amount163- */164-};165-166-/* possible values of the ftfmt_op field167- */168-#define FTFMT_SET_PARMS 1 /* set software parms */169-#define FTFMT_GET_PARMS 2 /* get software parms */170-#define FTFMT_FORMAT_TRACK 3 /* start formatting a tape track */171-#define FTFMT_STATUS 4 /* monitor formatting a tape track */172-#define FTFMT_VERIFY 5 /* verify the given segment */173-174-struct ftfmtparms {175- unsigned char ft_qicstd; /* QIC-40/QIC-80/QIC-3010/QIC-3020 */176- unsigned char ft_fmtcode; /* Refer to the QIC specs */177- unsigned char ft_fhm; /* floppy head max */178- unsigned char ft_ftm; /* floppy track max */179- unsigned short ft_spt; /* segments per track */180- unsigned short ft_tpc; /* tracks per cartridge */181-};182-183-struct ftfmttrack {184- unsigned int ft_track; /* track to format */185- unsigned char ft_gap3; /* size of gap3, for FORMAT_TRK */186-};187-188-struct ftfmtstatus {189- unsigned int ft_segment; /* segment currently being formatted */190-};191-192-struct ftfmtverify {193- unsigned int ft_segment; /* segment to verify */194- unsigned long ft_bsm; /* bsm as result of VERIFY cmd */195-};196-197-struct mtftformat {198- unsigned int fmt_op; /* operation to perform */199- union fmt_arg {200- struct ftfmtparms fmt_parms; /* format parameters */201- struct ftfmttrack fmt_track; /* ctrl while formatting */202- struct ftfmtstatus fmt_status;203- struct ftfmtverify fmt_verify; /* for verifying */ 204- } fmt_arg;205-};206-207-struct mtftcmd {208- unsigned int ft_wait_before; /* timeout to wait for drive to get ready 209- * before command is sent. Milliseconds210- */211- qic117_cmd_t ft_cmd; /* command to send */212- unsigned char ft_parm_cnt; /* zero: no parm is sent. */213- unsigned char ft_parms[3]; /* parameter(s) to send to214- * the drive. The parms are nibbles215- * driver sends cmd + 2 step pulses */216- unsigned int ft_result_bits; /* if non zero, number of bits217- * returned by the tape drive218- */219- unsigned int ft_result; /* the result returned by the tape drive*/220- unsigned int ft_wait_after; /* timeout to wait for drive to get ready221- * after command is sent. 0: don't wait */222- int ft_status; /* status returned by ready wait223- * undefined if timeout was 0.224- */225- int ft_error; /* error code if error status was set by 226- * command227- */228-};229-230/* mag tape io control commands */231#define MTIOCTOP _IOW('m', 1, struct mtop) /* do a mag tape op */232#define MTIOCGET _IOR('m', 2, struct mtget) /* get tape status */233#define MTIOCPOS _IOR('m', 3, struct mtpos) /* get tape position */234235-/* The next two are used by the QIC-02 driver for runtime reconfiguration.236- * See tpqic02.h for struct mtconfiginfo.237- */238-#define MTIOCGETCONFIG _IOR('m', 4, struct mtconfiginfo) /* get tape config */239-#define MTIOCSETCONFIG _IOW('m', 5, struct mtconfiginfo) /* set tape config */240-241-/* the next six are used by the floppy ftape drivers and its frontends242- * sorry, but MTIOCTOP commands are write only.243- */244-#define MTIOCRDFTSEG _IOWR('m', 6, struct mtftseg) /* read a segment */245-#define MTIOCWRFTSEG _IOWR('m', 7, struct mtftseg) /* write a segment */246-#define MTIOCVOLINFO _IOR('m', 8, struct mtvolinfo) /* info about volume */247-#define MTIOCGETSIZE _IOR('m', 9, struct mttapesize)/* get cartridge size*/248-#define MTIOCFTFORMAT _IOWR('m', 10, struct mtftformat) /* format ftape */249-#define MTIOCFTCMD _IOWR('m', 11, struct mtftcmd) /* send QIC-117 cmd */250251/* Generic Mag Tape (device independent) status macros for examining252 * mt_gstat -- HP-UX compatible.
···1011#include <linux/types.h>12#include <linux/ioctl.h>01314/*15 * Structures and definitions for mag tape io control commands···116#define MT_ISFTAPE_UNKNOWN 0x800000 /* obsolete */117#define MT_ISFTAPE_FLAG 0x80000011800000000000000000000000000119120/* structure for MTIOCPOS - mag tape get position command */121···150};15115200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000153/* mag tape io control commands */154#define MTIOCTOP _IOW('m', 1, struct mtop) /* do a mag tape op */155#define MTIOCGET _IOR('m', 2, struct mtget) /* get tape status */156#define MTIOCPOS _IOR('m', 3, struct mtpos) /* get tape position */157000000000000000158159/* Generic Mag Tape (device independent) status macros for examining160 * mt_gstat -- HP-UX compatible.
-290
include/linux/qic117.h
···1-#ifndef _QIC117_H2-#define _QIC117_H3-4-/*5- * Copyright (C) 1993-1996 Bas Laarhoven,6- * (C) 1997 Claus-Justus Heine.7-8- This program is free software; you can redistribute it and/or modify9- it under the terms of the GNU General Public License as published by10- the Free Software Foundation; either version 2, or (at your option)11- any later version.12-13- This program is distributed in the hope that it will be useful,14- but WITHOUT ANY WARRANTY; without even the implied warranty of15- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the16- GNU General Public License for more details.17-18- You should have received a copy of the GNU General Public License19- along with this program; see the file COPYING. If not, write to20- the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.21-22- *23- * $Source: /homes/cvs/ftape-stacked/include/linux/qic117.h,v $24- * $Revision: 1.2 $25- * $Date: 1997/10/05 19:19:32 $26- *27- * This file contains QIC-117 spec. related definitions for the28- * QIC-40/80/3010/3020 floppy-tape driver "ftape" for Linux.29- *30- * These data were taken from the Quarter-Inch Cartridge31- * Drive Standards, Inc. document titled:32- * `Common Command Set Interface Specification for Flexible33- * Disk Controller Based Minicartridge Tape Drives'34- * document QIC-117 Revision J, 28 Aug 96.35- * For more information, contact:36- * Quarter-Inch Cartridge Drive Standards, Inc.37- * 311 East Carrillo Street38- * Santa Barbara, California 9310139- * Telephone (805) 963-385340- * Fax (805) 962-154141- * WWW http://www.qic.org42- *43- * Current QIC standard revisions (of interest) are:44- * QIC-40-MC, Rev. M, 2 Sep 92.45- * QIC-80-MC, Rev. N, 20 Mar 96.46- * QIC-80-MC, Rev. K, 15 Dec 94.47- * QIC-113, Rev. G, 15 Jun 95.48- * QIC-117, Rev. J, 28 Aug 96.49- * QIC-122, Rev. B, 6 Mar 91.50- * QIC-130, Rev. C, 2 Sep 92.51- * QIC-3010-MC, Rev. F, 14 Jun 95.52- * QIC-3020-MC, Rev. G, 31 Aug 95.53- * QIC-CRF3, Rev. B, 15 Jun 95.54- * */55-56-/*57- * QIC-117 common command set rev. J.58- * These commands are sent to the tape unit59- * as number of pulses over the step line.60- */61-62-typedef enum {63- QIC_NO_COMMAND = 0,64- QIC_RESET = 1,65- QIC_REPORT_NEXT_BIT = 2,66- QIC_PAUSE = 3,67- QIC_MICRO_STEP_PAUSE = 4,68- QIC_ALTERNATE_TIMEOUT = 5,69- QIC_REPORT_DRIVE_STATUS = 6,70- QIC_REPORT_ERROR_CODE = 7,71- QIC_REPORT_DRIVE_CONFIGURATION = 8,72- QIC_REPORT_ROM_VERSION = 9,73- QIC_LOGICAL_FORWARD = 10,74- QIC_PHYSICAL_REVERSE = 11,75- QIC_PHYSICAL_FORWARD = 12,76- QIC_SEEK_HEAD_TO_TRACK = 13,77- QIC_SEEK_LOAD_POINT = 14,78- QIC_ENTER_FORMAT_MODE = 15,79- QIC_WRITE_REFERENCE_BURST = 16,80- QIC_ENTER_VERIFY_MODE = 17,81- QIC_STOP_TAPE = 18,82-/* commands 19-20: reserved */83- QIC_MICRO_STEP_HEAD_UP = 21,84- QIC_MICRO_STEP_HEAD_DOWN = 22,85- QIC_SOFT_SELECT = 23,86- QIC_SOFT_DESELECT = 24,87- QIC_SKIP_REVERSE = 25,88- QIC_SKIP_FORWARD = 26,89- QIC_SELECT_RATE = 27,90-/* command 27, in ccs2: Select Rate or Format */91- QIC_ENTER_DIAGNOSTIC_1 = 28,92- QIC_ENTER_DIAGNOSTIC_2 = 29,93- QIC_ENTER_PRIMARY_MODE = 30,94-/* command 31: vendor unique */95- QIC_REPORT_VENDOR_ID = 32,96- QIC_REPORT_TAPE_STATUS = 33,97- QIC_SKIP_EXTENDED_REVERSE = 34,98- QIC_SKIP_EXTENDED_FORWARD = 35,99- QIC_CALIBRATE_TAPE_LENGTH = 36,100- QIC_REPORT_FORMAT_SEGMENTS = 37,101- QIC_SET_FORMAT_SEGMENTS = 38,102-/* commands 39-45: reserved */103- QIC_PHANTOM_SELECT = 46,104- QIC_PHANTOM_DESELECT = 47105-} qic117_cmd_t;106-107-typedef enum {108- discretional = 0, required, ccs1, ccs2109-} qic_compatibility;110-111-typedef enum {112- unused, mode, motion, report113-} command_types;114-115-struct qic117_command_table {116- char *name;117- __u8 mask;118- __u8 state;119- __u8 cmd_type;120- __u8 non_intr;121- __u8 level;122-};123-124-#define QIC117_COMMANDS {\125-/* command mask state cmd_type */\126-/* | name | | | non_intr */\127-/* | | | | | | level */\128-/* 0*/ {NULL, 0x00, 0x00, mode, 0, discretional},\129-/* 1*/ {"soft reset", 0x00, 0x00, motion, 1, required},\130-/* 2*/ {"report next bit", 0x00, 0x00, report, 0, required},\131-/* 3*/ {"pause", 0x36, 0x24, motion, 1, required},\132-/* 4*/ {"micro step pause", 0x36, 0x24, motion, 1, required},\133-/* 5*/ {"alternate command timeout", 0x00, 0x00, mode, 0, required},\134-/* 6*/ {"report drive status", 0x00, 0x00, report, 0, required},\135-/* 7*/ {"report error code", 0x01, 0x01, report, 0, required},\136-/* 8*/ {"report drive configuration",0x00, 0x00, report, 0, required},\137-/* 9*/ {"report rom version", 0x00, 0x00, report, 0, required},\138-/*10*/ {"logical forward", 0x37, 0x25, motion, 0, required},\139-/*11*/ {"physical reverse", 0x17, 0x05, motion, 0, required},\140-/*12*/ {"physical forward", 0x17, 0x05, motion, 0, required},\141-/*13*/ {"seek head to track", 0x37, 0x25, motion, 0, required},\142-/*14*/ {"seek load point", 0x17, 0x05, motion, 1, required},\143-/*15*/ {"enter format mode", 0x1f, 0x05, mode, 0, required},\144-/*16*/ {"write reference burst", 0x1f, 0x05, motion, 1, required},\145-/*17*/ {"enter verify mode", 0x37, 0x25, mode, 0, required},\146-/*18*/ {"stop tape", 0x00, 0x00, motion, 1, required},\147-/*19*/ {"reserved (19)", 0x00, 0x00, unused, 0, discretional},\148-/*20*/ {"reserved (20)", 0x00, 0x00, unused, 0, discretional},\149-/*21*/ {"micro step head up", 0x02, 0x00, motion, 0, required},\150-/*22*/ {"micro step head down", 0x02, 0x00, motion, 0, required},\151-/*23*/ {"soft select", 0x00, 0x00, mode, 0, discretional},\152-/*24*/ {"soft deselect", 0x00, 0x00, mode, 0, discretional},\153-/*25*/ {"skip segments reverse", 0x36, 0x24, motion, 1, required},\154-/*26*/ {"skip segments forward", 0x36, 0x24, motion, 1, required},\155-/*27*/ {"select rate or format", 0x03, 0x01, mode, 0, required /* [ccs2] */},\156-/*28*/ {"enter diag mode 1", 0x00, 0x00, mode, 0, discretional},\157-/*29*/ {"enter diag mode 2", 0x00, 0x00, mode, 0, discretional},\158-/*30*/ {"enter primary mode", 0x00, 0x00, mode, 0, required},\159-/*31*/ {"vendor unique (31)", 0x00, 0x00, unused, 0, discretional},\160-/*32*/ {"report vendor id", 0x00, 0x00, report, 0, required},\161-/*33*/ {"report tape status", 0x04, 0x04, report, 0, ccs1},\162-/*34*/ {"skip extended reverse", 0x36, 0x24, motion, 1, ccs1},\163-/*35*/ {"skip extended forward", 0x36, 0x24, motion, 1, ccs1},\164-/*36*/ {"calibrate tape length", 0x17, 0x05, motion, 1, ccs2},\165-/*37*/ {"report format segments", 0x17, 0x05, report, 0, ccs2},\166-/*38*/ {"set format segments", 0x17, 0x05, mode, 0, ccs2},\167-/*39*/ {"reserved (39)", 0x00, 0x00, unused, 0, discretional},\168-/*40*/ {"vendor unique (40)", 0x00, 0x00, unused, 0, discretional},\169-/*41*/ {"vendor unique (41)", 0x00, 0x00, unused, 0, discretional},\170-/*42*/ {"vendor unique (42)", 0x00, 0x00, unused, 0, discretional},\171-/*43*/ {"vendor unique (43)", 0x00, 0x00, unused, 0, discretional},\172-/*44*/ {"vendor unique (44)", 0x00, 0x00, unused, 0, discretional},\173-/*45*/ {"vendor unique (45)", 0x00, 0x00, unused, 0, discretional},\174-/*46*/ {"phantom select", 0x00, 0x00, mode, 0, discretional},\175-/*47*/ {"phantom deselect", 0x00, 0x00, mode, 0, discretional},\176-}177-178-/*179- * Status bits returned by QIC_REPORT_DRIVE_STATUS180- */181-182-#define QIC_STATUS_READY 0x01 /* Drive is ready or idle. */183-#define QIC_STATUS_ERROR 0x02 /* Error detected, must read184- error code to clear this */185-#define QIC_STATUS_CARTRIDGE_PRESENT 0x04 /* Tape is present */186-#define QIC_STATUS_WRITE_PROTECT 0x08 /* Tape is write protected */187-#define QIC_STATUS_NEW_CARTRIDGE 0x10 /* New cartridge inserted, must188- read error status to clear. */189-#define QIC_STATUS_REFERENCED 0x20 /* Cartridge appears to have been190- formatted. */191-#define QIC_STATUS_AT_BOT 0x40 /* Cartridge is at physical192- beginning of tape. */193-#define QIC_STATUS_AT_EOT 0x80 /* Cartridge is at physical end194- of tape. */195-/*196- * Status bits returned by QIC_REPORT_DRIVE_CONFIGURATION197- */198-199-#define QIC_CONFIG_RATE_MASK 0x18200-#define QIC_CONFIG_RATE_SHIFT 3201-#define QIC_CONFIG_RATE_250 0202-#define QIC_CONFIG_RATE_500 2203-#define QIC_CONFIG_RATE_1000 3204-#define QIC_CONFIG_RATE_2000 1205-#define QIC_CONFIG_RATE_4000 0 /* since QIC-117 Rev. J */206-207-#define QIC_CONFIG_LONG 0x40 /* Extra Length Tape Detected */208-#define QIC_CONFIG_80 0x80 /* QIC-80 detected. */209-210-/*211- * Status bits returned by QIC_REPORT_TAPE_STATUS212- */213-214-#define QIC_TAPE_STD_MASK 0x0f215-#define QIC_TAPE_QIC40 0x01216-#define QIC_TAPE_QIC80 0x02217-#define QIC_TAPE_QIC3020 0x03218-#define QIC_TAPE_QIC3010 0x04219-220-#define QIC_TAPE_LEN_MASK 0x70221-#define QIC_TAPE_205FT 0x10222-#define QIC_TAPE_307FT 0x20223-#define QIC_TAPE_VARIABLE 0x30224-#define QIC_TAPE_1100FT 0x40225-#define QIC_TAPE_FLEX 0x60226-227-#define QIC_TAPE_WIDE 0x80228-229-/* Define a value (in feet) slightly higher than 230- * the possible maximum tape length.231- */232-#define QIC_TOP_TAPE_LEN 1500233-234-/*235- * Errors: List of error codes, and their severity.236- */237-238-typedef struct {239- char *message; /* Text describing the error. */240- unsigned int fatal:1; /* Non-zero if the error is fatal. */241-} ftape_error;242-243-#define QIC117_ERRORS {\244- /* 0*/ { "No error", 0, },\245- /* 1*/ { "Command Received while Drive Not Ready", 0, },\246- /* 2*/ { "Cartridge Not Present or Removed", 1, },\247- /* 3*/ { "Motor Speed Error (not within 1%)", 1, },\248- /* 4*/ { "Motor Speed Fault (jammed, or gross speed error", 1, },\249- /* 5*/ { "Cartridge Write Protected", 1, },\250- /* 6*/ { "Undefined or Reserved Command Code", 1, },\251- /* 7*/ { "Illegal Track Address Specified for Seek", 1, },\252- /* 8*/ { "Illegal Command in Report Subcontext", 0, },\253- /* 9*/ { "Illegal Entry into a Diagnostic Mode", 1, },\254- /*10*/ { "Broken Tape Detected (based on hole sensor)", 1, },\255- /*11*/ { "Warning--Read Gain Setting Error", 1, },\256- /*12*/ { "Command Received While Error Status Pending (obs)", 1, },\257- /*13*/ { "Command Received While New Cartridge Pending", 1, },\258- /*14*/ { "Command Illegal or Undefined in Primary Mode", 1, },\259- /*15*/ { "Command Illegal or Undefined in Format Mode", 1, },\260- /*16*/ { "Command Illegal or Undefined in Verify Mode", 1, },\261- /*17*/ { "Logical Forward Not at Logical BOT or no Format Segments in Format Mode", 1, },\262- /*18*/ { "Logical EOT Before All Segments generated", 1, },\263- /*19*/ { "Command Illegal When Cartridge Not Referenced", 1, },\264- /*20*/ { "Self-Diagnostic Failed (cannot be cleared)", 1, },\265- /*21*/ { "Warning EEPROM Not Initialized, Defaults Set", 1, },\266- /*22*/ { "EEPROM Corrupted or Hardware Failure", 1, },\267- /*23*/ { "Motion Time-out Error", 1, },\268- /*24*/ { "Data Segment Too Long -- Logical Forward or Pause", 1, },\269- /*25*/ { "Transmit Overrun (obs)", 1, },\270- /*26*/ { "Power On Reset Occurred", 0, },\271- /*27*/ { "Software Reset Occurred", 0, },\272- /*28*/ { "Diagnostic Mode 1 Error", 1, },\273- /*29*/ { "Diagnostic Mode 2 Error", 1, },\274- /*30*/ { "Command Received During Non-Interruptible Process", 1, },\275- /*31*/ { "Rate or Format Selection Error", 1, },\276- /*32*/ { "Illegal Command While in High Speed Mode", 1, },\277- /*33*/ { "Illegal Seek Segment Value", 1, },\278- /*34*/ { "Invalid Media", 1, },\279- /*35*/ { "Head Positioning Failure", 1, },\280- /*36*/ { "Write Reference Burst Failure", 1, },\281- /*37*/ { "Prom Code Missing", 1, },\282- /*38*/ { "Invalid Format", 1, },\283- /*39*/ { "EOT/BOT System Failure", 1, },\284- /*40*/ { "Prom A Checksum Error", 1, },\285- /*41*/ { "Drive Wakeup Reset Occurred", 1, },\286- /*42*/ { "Prom B Checksum Error", 1, },\287- /*43*/ { "Illegal Entry into Format Mode", 1, },\288-}289-290-#endif /* _QIC117_H */
···323int blocking_notifier_call_chain(struct blocking_notifier_head *nh,324 unsigned long val, void *v)325{326- int ret;327328- down_read(&nh->rwsem);329- ret = notifier_call_chain(&nh->head, val, v);330- up_read(&nh->rwsem);0000000331 return ret;332}333
···323int blocking_notifier_call_chain(struct blocking_notifier_head *nh,324 unsigned long val, void *v)325{326+ int ret = NOTIFY_DONE;327328+ /*329+ * We check the head outside the lock, but if this access is330+ * racy then it does not matter what the result of the test331+ * is, we re-check the list after having taken the lock anyway:332+ */333+ if (rcu_dereference(nh->head)) {334+ down_read(&nh->rwsem);335+ ret = notifier_call_chain(&nh->head, val, v);336+ up_read(&nh->rwsem);337+ }338 return ret;339}340