diff options
Diffstat (limited to 'include/linux')
36 files changed, 1056 insertions, 512 deletions
diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 4a446a19295..cedbbd806bf 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -86,6 +86,7 @@ header-y += if_plip.h header-y += if_ppp.h header-y += if_slip.h header-y += if_strip.h +header-y += if_tun.h header-y += if_tunnel.h header-y += in6.h header-y += in_route.h @@ -229,7 +230,6 @@ unifdef-y += if_link.h unifdef-y += if_pppol2tp.h unifdef-y += if_pppox.h unifdef-y += if_tr.h -unifdef-y += if_tun.h unifdef-y += if_vlan.h unifdef-y += if_wanpipe.h unifdef-y += igmp.h @@ -253,7 +253,7 @@ unifdef-y += kd.h unifdef-y += kernelcapi.h unifdef-y += kernel.h unifdef-y += keyboard.h -unifdef-$(CONFIG_HAVE_KVM) += kvm.h +unifdef-y += kvm.h unifdef-y += llc.h unifdef-y += loop.h unifdef-y += lp.h diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index 028ba3b523b..a6a6035a4e1 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -256,6 +256,7 @@ struct cgroup_subsys { void (*bind)(struct cgroup_subsys *ss, struct cgroup *root); int subsys_id; int active; + int disabled; int early_init; #define MAX_CGROUP_TYPE_NAMELEN 32 const char *name; diff --git a/include/linux/clocksource.h b/include/linux/clocksource.h index 85778a4b120..35094479ca5 100644 --- a/include/linux/clocksource.h +++ b/include/linux/clocksource.h @@ -216,6 +216,7 @@ static inline void clocksource_calculate_interval(struct clocksource *c, /* used to install a new clocksource */ extern int clocksource_register(struct clocksource*); extern void clocksource_unregister(struct clocksource*); +extern void clocksource_touch_watchdog(void); extern struct clocksource* clocksource_get_next(void); extern void clocksource_change_rating(struct clocksource *cs, int rating); extern void clocksource_resume(void); diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 34d44069829..b4d84ed6187 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -95,12 +95,17 @@ enum dma_transaction_type { #define DMA_TX_TYPE_END (DMA_INTERRUPT + 1) /** - * enum dma_prep_flags - DMA flags to augment operation preparation + * enum dma_ctrl_flags - DMA flags to augment operation preparation, + * control completion, and communicate status. * @DMA_PREP_INTERRUPT - trigger an interrupt (callback) upon completion of * this transaction + * @DMA_CTRL_ACK - the descriptor cannot be reused until the client + * acknowledges receipt, i.e. has has a chance to establish any + * dependency chains */ -enum dma_prep_flags { +enum dma_ctrl_flags { DMA_PREP_INTERRUPT = (1 << 0), + DMA_CTRL_ACK = (1 << 1), }; /** @@ -211,8 +216,8 @@ typedef void (*dma_async_tx_callback)(void *dma_async_param); * ---dma generic offload fields--- * @cookie: tracking cookie for this transaction, set to -EBUSY if * this tx is sitting on a dependency list - * @ack: the descriptor can not be reused until the client acknowledges - * receipt, i.e. has has a chance to establish any dependency chains + * @flags: flags to augment operation preparation, control completion, and + * communicate status * @phys: physical address of the descriptor * @tx_list: driver common field for operations that require multiple * descriptors @@ -221,23 +226,20 @@ typedef void (*dma_async_tx_callback)(void *dma_async_param); * @callback: routine to call after this operation is complete * @callback_param: general parameter to pass to the callback routine * ---async_tx api specific fields--- - * @depend_list: at completion this list of transactions are submitted - * @depend_node: allow this transaction to be executed after another - * transaction has completed, possibly on another channel + * @next: at completion submit this descriptor * @parent: pointer to the next level up in the dependency chain - * @lock: protect the dependency list + * @lock: protect the parent and next pointers */ struct dma_async_tx_descriptor { dma_cookie_t cookie; - int ack; + enum dma_ctrl_flags flags; /* not a 'long' to pack with cookie */ dma_addr_t phys; struct list_head tx_list; struct dma_chan *chan; dma_cookie_t (*tx_submit)(struct dma_async_tx_descriptor *tx); dma_async_tx_callback callback; void *callback_param; - struct list_head depend_list; - struct list_head depend_node; + struct dma_async_tx_descriptor *next; struct dma_async_tx_descriptor *parent; spinlock_t lock; }; @@ -261,7 +263,6 @@ struct dma_async_tx_descriptor { * @device_prep_dma_zero_sum: prepares a zero_sum operation * @device_prep_dma_memset: prepares a memset operation * @device_prep_dma_interrupt: prepares an end of chain interrupt operation - * @device_dependency_added: async_tx notifies the channel about new deps * @device_issue_pending: push pending transactions to hardware */ struct dma_device { @@ -294,9 +295,8 @@ struct dma_device { struct dma_chan *chan, dma_addr_t dest, int value, size_t len, unsigned long flags); struct dma_async_tx_descriptor *(*device_prep_dma_interrupt)( - struct dma_chan *chan); + struct dma_chan *chan, unsigned long flags); - void (*device_dependency_added)(struct dma_chan *chan); enum dma_status (*device_is_tx_complete)(struct dma_chan *chan, dma_cookie_t cookie, dma_cookie_t *last, dma_cookie_t *used); @@ -321,7 +321,13 @@ void dma_async_tx_descriptor_init(struct dma_async_tx_descriptor *tx, static inline void async_tx_ack(struct dma_async_tx_descriptor *tx) { - tx->ack = 1; + tx->flags |= DMA_CTRL_ACK; +} + +static inline int +async_tx_test_ack(struct dma_async_tx_descriptor *tx) +{ + return tx->flags & DMA_CTRL_ACK; } #define first_dma_cap(mask) __first_dma_cap(&(mask)) diff --git a/include/linux/hdreg.h b/include/linux/hdreg.h index e38e75967e7..c37e9241fae 100644 --- a/include/linux/hdreg.h +++ b/include/linux/hdreg.h @@ -422,9 +422,11 @@ struct hd_geometry { #define HDIO_SET_NOWERR 0x0325 /* change ignore-write-error flag */ #define HDIO_SET_DMA 0x0326 /* change use-dma flag */ #define HDIO_SET_PIO_MODE 0x0327 /* reconfig interface to new speed */ +#ifndef __KERNEL__ #define HDIO_SCAN_HWIF 0x0328 /* register and (re)scan interface */ -#define HDIO_SET_NICE 0x0329 /* set nice flags */ #define HDIO_UNREGISTER_HWIF 0x032a /* unregister interface */ +#endif +#define HDIO_SET_NICE 0x0329 /* set nice flags */ #define HDIO_SET_WCACHE 0x032b /* change write cache enable-disable */ #define HDIO_SET_ACOUSTIC 0x032c /* change acoustic behavior */ #define HDIO_SET_BUSSTATE 0x032d /* set the bus state of the hwif */ diff --git a/include/linux/hpet.h b/include/linux/hpet.h index 9cd94bfd07e..2dc29ce6c8e 100644 --- a/include/linux/hpet.h +++ b/include/linux/hpet.h @@ -64,7 +64,7 @@ struct hpet { */ #define Tn_INT_ROUTE_CAP_MASK (0xffffffff00000000ULL) -#define Tn_INT_ROUTE_CAP_SHIFT (32UL) +#define Tn_INI_ROUTE_CAP_SHIFT (32UL) #define Tn_FSB_INT_DELCAP_MASK (0x8000UL) #define Tn_FSB_INT_DELCAP_SHIFT (15) #define Tn_FSB_EN_CNF_MASK (0x4000UL) diff --git a/include/linux/hrtimer.h b/include/linux/hrtimer.h index 1ad56a7b2f7..56f3236da82 100644 --- a/include/linux/hrtimer.h +++ b/include/linux/hrtimer.h @@ -173,7 +173,6 @@ struct hrtimer_clock_base { * struct hrtimer_cpu_base - the per cpu clock bases * @lock: lock protecting the base and associated clock bases * and timers - * @lock_key: the lock_class_key for use with lockdep * @clock_base: array of clock bases for this cpu * @curr_timer: the timer which is executing a callback right now * @expires_next: absolute time of the next event which was scheduled @@ -189,7 +188,6 @@ struct hrtimer_clock_base { */ struct hrtimer_cpu_base { spinlock_t lock; - struct lock_class_key lock_key; struct hrtimer_clock_base clock_base[HRTIMER_MAX_CLOCK_BASES]; struct list_head cb_pending; #ifdef CONFIG_HIGH_RES_TIMERS diff --git a/include/linux/ide.h b/include/linux/ide.h index bc26b2f2735..6c39482fd1a 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -82,24 +82,10 @@ typedef unsigned char byte; /* used everywhere */ #define IDE_FEATURE_OFFSET IDE_ERROR_OFFSET #define IDE_COMMAND_OFFSET IDE_STATUS_OFFSET - -#define IDE_DATA_REG (HWIF(drive)->io_ports[IDE_DATA_OFFSET]) -#define IDE_ERROR_REG (HWIF(drive)->io_ports[IDE_ERROR_OFFSET]) -#define IDE_NSECTOR_REG (HWIF(drive)->io_ports[IDE_NSECTOR_OFFSET]) -#define IDE_SECTOR_REG (HWIF(drive)->io_ports[IDE_SECTOR_OFFSET]) -#define IDE_LCYL_REG (HWIF(drive)->io_ports[IDE_LCYL_OFFSET]) -#define IDE_HCYL_REG (HWIF(drive)->io_ports[IDE_HCYL_OFFSET]) -#define IDE_SELECT_REG (HWIF(drive)->io_ports[IDE_SELECT_OFFSET]) -#define IDE_STATUS_REG (HWIF(drive)->io_ports[IDE_STATUS_OFFSET]) -#define IDE_CONTROL_REG (HWIF(drive)->io_ports[IDE_CONTROL_OFFSET]) -#define IDE_IRQ_REG (HWIF(drive)->io_ports[IDE_IRQ_OFFSET]) - -#define IDE_FEATURE_REG IDE_ERROR_REG -#define IDE_COMMAND_REG IDE_STATUS_REG -#define IDE_ALTSTATUS_REG IDE_CONTROL_REG -#define IDE_IREASON_REG IDE_NSECTOR_REG -#define IDE_BCOUNTL_REG IDE_LCYL_REG -#define IDE_BCOUNTH_REG IDE_HCYL_REG +#define IDE_ALTSTATUS_OFFSET IDE_CONTROL_OFFSET +#define IDE_IREASON_OFFSET IDE_NSECTOR_OFFSET +#define IDE_BCOUNTL_OFFSET IDE_LCYL_OFFSET +#define IDE_BCOUNTH_OFFSET IDE_HCYL_OFFSET #define OK_STAT(stat,good,bad) (((stat)&((good)|(bad)))==(good)) #define BAD_R_STAT (BUSY_STAT | ERR_STAT) @@ -169,7 +155,7 @@ enum { ide_unknown, ide_generic, ide_pci, ide_rz1000, ide_trm290, ide_cmd646, ide_cy82c693, ide_4drives, ide_pmac, ide_etrax100, ide_acorn, - ide_au1xxx, ide_palm3710, ide_forced + ide_au1xxx, ide_palm3710 }; typedef u8 hwif_chipset_t; @@ -186,14 +172,9 @@ typedef struct hw_regs_s { } hw_regs_t; struct hwif_s * ide_find_port(unsigned long); -struct hwif_s *ide_deprecated_find_port(unsigned long); void ide_init_port_data(struct hwif_s *, unsigned int); void ide_init_port_hw(struct hwif_s *, hw_regs_t *); -struct ide_drive_s; -int ide_register_hw(hw_regs_t *, void (*)(struct ide_drive_s *), - struct hwif_s **); - static inline void ide_std_init_ports(hw_regs_t *hw, unsigned long io_addr, unsigned long ctl_addr) @@ -213,45 +194,6 @@ static inline void ide_std_init_ports(hw_regs_t *hw, #define MAX_HWIFS CONFIG_IDE_MAX_HWIFS #endif -/* needed on alpha, x86/x86_64, ia64, mips, ppc32 and sh */ -#ifndef IDE_ARCH_OBSOLETE_DEFAULTS -# define ide_default_io_base(index) (0) -# define ide_default_irq(base) (0) -# define ide_init_default_irq(base) (0) -#endif - -#ifdef CONFIG_IDE_ARCH_OBSOLETE_INIT -static inline void ide_init_hwif_ports(hw_regs_t *hw, - unsigned long io_addr, - unsigned long ctl_addr, - int *irq) -{ - if (!ctl_addr) - ide_std_init_ports(hw, io_addr, ide_default_io_ctl(io_addr)); - else - ide_std_init_ports(hw, io_addr, ctl_addr); - - if (irq) - *irq = 0; - - hw->io_ports[IDE_IRQ_OFFSET] = 0; - -#ifdef CONFIG_PPC32 - if (ppc_ide_md.ide_init_hwif) - ppc_ide_md.ide_init_hwif(hw, io_addr, ctl_addr, irq); -#endif -} -#else -static inline void ide_init_hwif_ports(hw_regs_t *hw, - unsigned long io_addr, - unsigned long ctl_addr, - int *irq) -{ - if (io_addr || ctl_addr) - printk(KERN_WARNING "%s: must not be called\n", __FUNCTION__); -} -#endif /* CONFIG_IDE_ARCH_OBSOLETE_INIT */ - /* Currently only m68k, apus and m8xx need it */ #ifndef IDE_ARCH_ACK_INTR # define ide_ack_intr(hwif) (1) @@ -406,7 +348,7 @@ typedef struct ide_drive_s { u8 wcache; /* status of write cache */ u8 acoustic; /* acoustic management */ u8 media; /* disk, cdrom, tape, floppy, ... */ - u8 ctl; /* "normal" value for IDE_CONTROL_REG */ + u8 ctl; /* "normal" value for Control register */ u8 ready_stat; /* min status value for drive ready */ u8 mult_count; /* current multiple sector setting */ u8 mult_req; /* requested multiple sector setting */ @@ -507,8 +449,6 @@ typedef struct hwif_s { void (*maskproc)(ide_drive_t *, int); /* check host's drive quirk list */ void (*quirkproc)(ide_drive_t *); - /* driver soft-power interface */ - int (*busproc)(ide_drive_t *, int); #endif u8 (*mdma_filter)(ide_drive_t *); u8 (*udma_filter)(ide_drive_t *); @@ -578,7 +518,6 @@ typedef struct hwif_s { unsigned noprobe : 1; /* don't probe for this interface */ unsigned present : 1; /* this interface exists */ - unsigned hold : 1; /* this interface is always present */ unsigned serialized : 1; /* serialized all channel operation */ unsigned sharing_irq: 1; /* 1 = sharing irq with another hwif */ unsigned reset : 1; /* reset after probe */ @@ -586,7 +525,9 @@ typedef struct hwif_s { unsigned mmio : 1; /* host uses MMIO */ unsigned straight8 : 1; /* Alan's straight 8 check */ - struct device gendev; + struct device gendev; + struct device *portdev; + struct completion gendev_rel_comp; /* To deal with device release() */ void *hwif_data; /* extra hwif data */ @@ -647,6 +588,68 @@ int set_io_32bit(ide_drive_t *, int); int set_pio_mode(ide_drive_t *, int); int set_using_dma(ide_drive_t *, int); +/* ATAPI packet command flags */ +enum { + /* set when an error is considered normal - no retry (ide-tape) */ + PC_FLAG_ABORT = (1 << 0), + PC_FLAG_SUPPRESS_ERROR = (1 << 1), + PC_FLAG_WAIT_FOR_DSC = (1 << 2), + PC_FLAG_DMA_OK = (1 << 3), + PC_FLAG_DMA_RECOMMENDED = (1 << 4), + PC_FLAG_DMA_IN_PROGRESS = (1 << 5), + PC_FLAG_DMA_ERROR = (1 << 6), + PC_FLAG_WRITING = (1 << 7), + /* command timed out */ + PC_FLAG_TIMEDOUT = (1 << 8), +}; + +struct ide_atapi_pc { + /* actual packet bytes */ + u8 c[12]; + /* incremented on each retry */ + int retries; + int error; + + /* bytes to transfer */ + int req_xfer; + /* bytes actually transferred */ + int xferred; + + /* data buffer */ + u8 *buf; + /* current buffer position */ + u8 *cur_pos; + int buf_size; + /* missing/available data on the current buffer */ + int b_count; + + /* the corresponding request */ + struct request *rq; + + unsigned long flags; + + /* + * those are more or less driver-specific and some of them are subject + * to change/removal later. + */ + u8 pc_buf[256]; + void (*idefloppy_callback) (ide_drive_t *); + ide_startstop_t (*idetape_callback) (ide_drive_t *); + + /* idetape only */ + struct idetape_bh *bh; + char *b_data; + + /* idescsi only for now */ + struct scatterlist *sg; + unsigned int sg_cnt; + + struct scsi_cmnd *scsi_cmd; + void (*done) (struct scsi_cmnd *); + + unsigned long timeout; +}; + #ifdef CONFIG_IDE_PROC_FS /* * configurable drive settings @@ -691,6 +694,7 @@ void proc_ide_create(void); void proc_ide_destroy(void); void ide_proc_register_port(ide_hwif_t *); void ide_proc_port_register_devices(ide_hwif_t *); +void ide_proc_unregister_device(ide_drive_t *); void ide_proc_unregister_port(ide_hwif_t *); void ide_proc_register_driver(ide_drive_t *, ide_driver_t *); void ide_proc_unregister_driver(ide_drive_t *, ide_driver_t *); @@ -724,6 +728,7 @@ static inline void proc_ide_create(void) { ; } static inline void proc_ide_destroy(void) { ; } static inline void ide_proc_register_port(ide_hwif_t *hwif) { ; } static inline void ide_proc_port_register_devices(ide_hwif_t *hwif) { ; } +static inline void ide_proc_unregister_device(ide_drive_t *drive) { ; } static inline void ide_proc_unregister_port(ide_hwif_t *hwif) { ; } static inline void ide_proc_register_driver(ide_drive_t *drive, ide_driver_t *driver) { ; } static inline void ide_proc_unregister_driver(ide_drive_t *drive, ide_driver_t *driver) { ; } @@ -990,7 +995,6 @@ extern void do_ide_request(struct request_queue *); void ide_init_disk(struct gendisk *, ide_drive_t *); #ifdef CONFIG_IDEPCI_PCIBUS_ORDER -extern int ide_scan_direction; extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *owner, const char *mod_name); #define ide_pci_register_driver(d) __ide_pci_register_driver(d, THIS_MODULE, KBUILD_MODNAME) #else @@ -1195,7 +1199,7 @@ static inline void ide_acpi_set_state(ide_hwif_t *hwif, int on) {} void ide_remove_port_from_hwgroup(ide_hwif_t *); extern int ide_hwif_request_regions(ide_hwif_t *hwif); extern void ide_hwif_release_regions(ide_hwif_t* hwif); -void ide_unregister(unsigned int, int, int); +void ide_unregister(unsigned int); void ide_register_region(struct gendisk *); void ide_unregister_region(struct gendisk *); @@ -1204,6 +1208,8 @@ void ide_undecoded_slave(ide_drive_t *); int ide_device_add_all(u8 *idx, const struct ide_port_info *); int ide_device_add(u8 idx[4], const struct ide_port_info *); +void ide_port_unregister_devices(ide_hwif_t *); +void ide_port_scan(ide_hwif_t *); static inline void *ide_get_hwifdata (ide_hwif_t * hwif) { @@ -1279,6 +1285,7 @@ extern struct mutex ide_cfg_mtx; #define local_irq_set(flags) do { local_save_flags((flags)); local_irq_enable_in_hardirq(); } while (0) extern struct bus_type ide_bus_type; +extern struct class *ide_port_class; /* check if CACHE FLUSH (EXT) command is supported (bits defined in ATA-6) */ #define ide_id_has_flush_cache(id) ((id)->cfs_enable_2 & 0x3000) @@ -1307,7 +1314,10 @@ static inline ide_drive_t *ide_get_paired_drive(ide_drive_t *drive) static inline void ide_set_irq(ide_drive_t *drive, int on) { - drive->hwif->OUTB(drive->ctl | (on ? 0 : 2), IDE_CONTROL_REG); + ide_hwif_t *hwif = drive->hwif; + + hwif->OUTB(drive->ctl | (on ? 0 : 2), + hwif->io_ports[IDE_CONTROL_OFFSET]); } static inline u8 ide_read_status(ide_drive_t *drive) @@ -1331,4 +1341,26 @@ static inline u8 ide_read_error(ide_drive_t *drive) return hwif->INB(hwif->io_ports[IDE_ERROR_OFFSET]); } +/* + * Too bad. The drive wants to send us data which we are not ready to accept. + * Just throw it away. + */ +static inline void ide_atapi_discard_data(ide_drive_t *drive, unsigned bcount) +{ + ide_hwif_t *hwif = drive->hwif; + + /* FIXME: use ->atapi_input_bytes */ + while (bcount--) + (void)hwif->INB(hwif->io_ports[IDE_DATA_OFFSET]); +} + +static inline void ide_atapi_write_zeros(ide_drive_t *drive, unsigned bcount) +{ + ide_hwif_t *hwif = drive->hwif; + + /* FIXME: use ->atapi_output_bytes */ + while (bcount--) + hwif->OUTB(0, hwif->io_ports[IDE_DATA_OFFSET]); +} + #endif /* _IDE_H */ diff --git a/include/linux/if_tun.h b/include/linux/if_tun.h index 72f1c5f47be..8c71fe2fb1f 100644 --- a/include/linux/if_tun.h +++ b/include/linux/if_tun.h @@ -18,47 +18,8 @@ #ifndef __IF_TUN_H #define __IF_TUN_H -/* Uncomment to enable debugging */ -/* #define TUN_DEBUG 1 */ - #include <linux/types.h> -#ifdef __KERNEL__ - -#ifdef TUN_DEBUG -#define DBG if(tun->debug)printk -#define DBG1 if(debug==2)printk -#else -#define DBG( a... ) -#define DBG1( a... ) -#endif - -struct tun_struct { - struct list_head list; - unsigned long flags; - int attached; - uid_t owner; - gid_t group; - - wait_queue_head_t read_wait; - struct sk_buff_head readq; - - struct net_device *dev; - - struct fasync_struct *fasync; - - unsigned long if_flags; - u8 dev_addr[ETH_ALEN]; - u32 chr_filter[2]; - u32 net_filter[2]; - -#ifdef TUN_DEBUG - int debug; -#endif -}; - -#endif /* __KERNEL__ */ - /* Read queue size */ #define TUN_READQ_SIZE 500 diff --git a/include/linux/input.h b/include/linux/input.h index 1bdc39a8c76..cae2c35d120 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -1227,12 +1227,13 @@ void input_free_device(struct input_dev *dev); static inline struct input_dev *input_get_device(struct input_dev *dev) { - return to_input_dev(get_device(&dev->dev)); + return dev ? to_input_dev(get_device(&dev->dev)) : NULL; } static inline void input_put_device(struct input_dev *dev) { - put_device(&dev->dev); + if (dev) + put_device(&dev->dev); } static inline void *input_get_drvdata(struct input_dev *dev) diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index f8ab4ce7056..b5fef13148b 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -102,6 +102,25 @@ extern void disable_irq_nosync(unsigned int irq); extern void disable_irq(unsigned int irq); extern void enable_irq(unsigned int irq); +#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS) + +extern int irq_set_affinity(unsigned int irq, cpumask_t cpumask); +extern int irq_can_set_affinity(unsigned int irq); + +#else /* CONFIG_SMP */ + +static inline int irq_set_affinity(unsigned int irq, cpumask_t cpumask) +{ + return -EINVAL; +} + +static inline int irq_can_set_affinity(unsigned int irq) +{ + return 0; +} + +#endif /* CONFIG_SMP && CONFIG_GENERIC_HARDIRQS */ + #ifdef CONFIG_GENERIC_HARDIRQS /* * Special lockdep variants of irq disabling/enabling. diff --git a/include/linux/iocontext.h b/include/linux/iocontext.h index 1b4ccf25b4d..2b7a1187cb2 100644 --- a/include/linux/iocontext.h +++ b/include/linux/iocontext.h @@ -2,6 +2,7 @@ #define IOCONTEXT_H #include <linux/radix-tree.h> +#include <linux/rcupdate.h> /* * This is the per-process anticipatory I/O scheduler state. @@ -54,6 +55,8 @@ struct cfq_io_context { void (*dtor)(struct io_context *); /* destructor */ void (*exit)(struct io_context *); /* called on task exit */ + + struct rcu_head rcu_head; }; /* @@ -88,8 +91,10 @@ static inline struct io_context *ioc_task_link(struct io_context *ioc) * if ref count is zero, don't allow sharing (ioc is going away, it's * a race). */ - if (ioc && atomic_inc_not_zero(&ioc->refcount)) + if (ioc && atomic_inc_not_zero(&ioc->refcount)) { + atomic_inc(&ioc->nr_tasks); return ioc; + } return NULL; } diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 4aaefc349a4..134c8e5cf07 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -53,7 +53,7 @@ struct ipv6_opt_hdr { /* * TLV encoded option data follows. */ -}; +} __attribute__ ((packed)); /* required for some archs */ #define ipv6_destopt_hdr ipv6_opt_hdr #define ipv6_hopopt_hdr ipv6_opt_hdr diff --git a/include/linux/irq.h b/include/linux/irq.h index 176e5e790a4..1883a85625d 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -228,21 +228,11 @@ static inline void set_pending_irq(unsigned int irq, cpumask_t mask) #endif /* CONFIG_GENERIC_PENDING_IRQ */ -extern int irq_set_affinity(unsigned int irq, cpumask_t cpumask); -extern int irq_can_set_affinity(unsigned int irq); - #else /* CONFIG_SMP */ #define move_native_irq(x) #define move_masked_irq(x) -static inline int irq_set_affinity(unsigned int irq, cpumask_t cpumask) -{ - return -EINVAL; -} - -static inline int irq_can_set_affinity(unsigned int irq) { return 0; } - #endif /* CONFIG_SMP */ #ifdef CONFIG_IRQBALANCE diff --git a/include/linux/kgdb.h b/include/linux/kgdb.h new file mode 100644 index 00000000000..9757b1a6d9d --- /dev/null +++ b/include/linux/kgdb.h @@ -0,0 +1,281 @@ +/* + * This provides the callbacks and functions that KGDB needs to share between + * the core, I/O and arch-specific portions. + * + * Author: Amit Kale <amitkale@linsyssoft.com> and + * Tom Rini <trini@kernel.crashing.org> + * + * 2001-2004 (c) Amit S. Kale and 2003-2005 (c) MontaVista Software, Inc. + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ +#ifndef _KGDB_H_ +#define _KGDB_H_ + +#include <linux/serial_8250.h> +#include <linux/linkage.h> +#include <linux/init.h> + +#include <asm/atomic.h> +#include <asm/kgdb.h> + +struct pt_regs; + +/** + * kgdb_skipexception - (optional) exit kgdb_handle_exception early + * @exception: Exception vector number + * @regs: Current &struct pt_regs. + * + * On some architectures it is required to skip a breakpoint + * exception when it occurs after a breakpoint has been removed. + * This can be implemented in the architecture specific portion of + * for kgdb. + */ +extern int kgdb_skipexception(int exception, struct pt_regs *regs); + +/** + * kgdb_post_primary_code - (optional) Save error vector/code numbers. + * @regs: Original pt_regs. + * @e_vector: Original error vector. + * @err_code: Original error code. + * + * This is usually needed on architectures which support SMP and + * KGDB. This function is called after all the secondary cpus have + * been put to a know spin state and the primary CPU has control over + * KGDB. + */ +extern void kgdb_post_primary_code(struct pt_regs *regs, int e_vector, + int err_code); + +/** + * kgdb_disable_hw_debug - (optional) Disable hardware debugging hook + * @regs: Current &struct pt_regs. + * + * This function will be called if the particular architecture must + * disable hardware debugging while it is processing gdb packets or + * handling exception. + */ +extern void kgdb_disable_hw_debug(struct pt_regs *regs); + +struct tasklet_struct; +struct task_struct; +struct uart_port; + +/** + * kgdb_breakpoint - compiled in breakpoint + * + * This will be impelmented a static inline per architecture. This + * function is called by the kgdb core to execute an architecture + * specific trap to cause kgdb to enter the exception processing. + * + */ +void kgdb_breakpoint(void); + +extern int kgdb_connected; + +extern atomic_t kgdb_setting_breakpoint; +extern atomic_t kgdb_cpu_doing_single_step; + +extern struct task_struct *kgdb_usethread; +extern struct task_struct *kgdb_contthread; + +enum kgdb_bptype { + BP_BREAKPOINT = 0, + BP_HARDWARE_BREAKPOINT, + BP_WRITE_WATCHPOINT, + BP_READ_WATCHPOINT, + BP_ACCESS_WATCHPOINT +}; + +enum kgdb_bpstate { + BP_UNDEFINED = 0, + BP_REMOVED, + BP_SET, + BP_ACTIVE +}; + +struct kgdb_bkpt { + unsigned long bpt_addr; + unsigned char saved_instr[BREAK_INSTR_SIZE]; + enum kgdb_bptype type; + enum kgdb_bpstate state; +}; + +#ifndef KGDB_MAX_BREAKPOINTS +# define KGDB_MAX_BREAKPOINTS 1000 +#endif + +#define KGDB_HW_BREAKPOINT 1 + +/* + * Functions each KGDB-supporting architecture must provide: + */ + +/** + * kgdb_arch_init - Perform any architecture specific initalization. + * + * This function will handle the initalization of any architecture + * specific callbacks. + */ +extern int kgdb_arch_init(void); + +/** + * kgdb_arch_exit - Perform any architecture specific uninitalization. + * + * This function will handle the uninitalization of any architecture + * specific callbacks, for dynamic registration and unregistration. + */ +extern void kgdb_arch_exit(void); + +/** + * pt_regs_to_gdb_regs - Convert ptrace regs to GDB regs + * @gdb_regs: A pointer to hold the registers in the order GDB wants. + * @regs: The &struct pt_regs of the current process. + * + * Convert the pt_regs in @regs into the format for registers that + * GDB expects, stored in @gdb_regs. + */ +extern void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *regs); + +/** + * sleeping_thread_to_gdb_regs - Convert ptrace regs to GDB regs + * @gdb_regs: A pointer to hold the registers in the order GDB wants. + * @p: The &struct task_struct of the desired process. + * + * Convert the register values of the sleeping process in @p to + * the format that GDB expects. + * This function is called when kgdb does not have access to the + * &struct pt_regs and therefore it should fill the gdb registers + * @gdb_regs with what has been saved in &struct thread_struct + * thread field during switch_to. + */ +extern void +sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *p); + +/** + * gdb_regs_to_pt_regs - Convert GDB regs to ptrace regs. + * @gdb_regs: A pointer to hold the registers we've received from GDB. + * @regs: A pointer to a &struct pt_regs to hold these values in. + * + * Convert the GDB regs in @gdb_regs into the pt_regs, and store them + * in @regs. + */ +extern void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *regs); + +/** + * kgdb_arch_handle_exception - Handle architecture specific GDB packets. + * @vector: The error vector of the exception that happened. + * @signo: The signal number of the exception that happened. + * @err_code: The error code of the exception that happened. + * @remcom_in_buffer: The buffer of the packet we have read. + * @remcom_out_buffer: The buffer of %BUFMAX bytes to write a packet into. + * @regs: The &struct pt_regs of the current process. + * + * This function MUST handle the 'c' and 's' command packets, + * as well packets to set / remove a hardware breakpoint, if used. + * If there are additional packets which the hardware needs to handle, + * they are handled here. The code should return -1 if it wants to + * process more packets, and a %0 or %1 if it wants to exit from the + * kgdb callback. + */ +extern int +kgdb_arch_handle_exception(int vector, int signo, int err_code, + char *remcom_in_buffer, + char *remcom_out_buffer, + struct pt_regs *regs); + +/** + * kgdb_roundup_cpus - Get other CPUs into a holding pattern + * @flags: Current IRQ state + * + * On SMP systems, we need to get the attention of the other CPUs + * and get them be in a known state. This should do what is needed + * to get the other CPUs to call kgdb_wait(). Note that on some arches, + * the NMI approach is not used for rounding up all the CPUs. For example, + * in case of MIPS, smp_call_function() is used to roundup CPUs. In + * this case, we have to make sure that interrupts are enabled before + * calling smp_call_function(). The argument to this function is + * the flags that will be used when restoring the interrupts. There is + * local_irq_save() call before kgdb_roundup_cpus(). + * + * On non-SMP systems, this is not called. + */ +extern void kgdb_roundup_cpus(unsigned long flags); + +/* Optional functions. */ +extern int kgdb_validate_break_address(unsigned long addr); +extern int kgdb_arch_set_breakpoint(unsigned long addr, char *saved_instr); +extern int kgdb_arch_remove_breakpoint(unsigned long addr, char *bundle); + +/** + * struct kgdb_arch - Describe architecture specific values. + * @gdb_bpt_instr: The instruction to trigger a breakpoint. + * @flags: Flags for the breakpoint, currently just %KGDB_HW_BREAKPOINT. + * @set_breakpoint: Allow an architecture to specify how to set a software + * breakpoint. + * @remove_breakpoint: Allow an architecture to specify how to remove a + * software breakpoint. + * @set_hw_breakpoint: Allow an architecture to specify how to set a hardware + * breakpoint. + * @remove_hw_breakpoint: Allow an architecture to specify how to remove a + * hardware breakpoint. + * @remove_all_hw_break: Allow an architecture to specify how to remove all + * hardware breakpoints. + * @correct_hw_break: Allow an architecture to specify how to correct the + * hardware debug registers. + */ +struct kgdb_arch { + unsigned char gdb_bpt_instr[BREAK_INSTR_SIZE]; + unsigned long flags; + + int (*set_breakpoint)(unsigned long, char *); + int (*remove_breakpoint)(unsigned long, char *); + int (*set_hw_breakpoint)(unsigned long, int, enum kgdb_bptype); + int (*remove_hw_breakpoint)(unsigned long, int, enum kgdb_bptype); + void (*remove_all_hw_break)(void); + void (*correct_hw_break)(void); +}; + +/** + * struct kgdb_io - Describe the interface for an I/O driver to talk with KGDB. + * @name: Name of the I/O driver. + * @read_char: Pointer to a function that will return one char. + * @write_char: Pointer to a function that will write one char. + * @flush: Pointer to a function that will flush any pending writes. + * @init: Pointer to a function that will initialize the device. + * @pre_exception: Pointer to a function that will do any prep work for + * the I/O driver. + * @post_exception: Pointer to a function that will do any cleanup work + * for the I/O driver. + */ +struct kgdb_io { + const char *name; + int (*read_char) (void); + void (*write_char) (u8); + void (*flush) (void); + int (*init) (void); + void (*pre_exception) (void); + void (*post_exception) (void); +}; + +extern struct kgdb_arch arch_kgdb_ops; + +extern int kgdb_register_io_module(struct kgdb_io *local_kgdb_io_ops); +extern void kgdb_unregister_io_module(struct kgdb_io *local_kgdb_io_ops); + +extern int kgdb_hex2long(char **ptr, long *long_val); +extern int kgdb_mem2hex(char *mem, char *buf, int count); +extern int kgdb_hex2mem(char *buf, char *mem, int count); + +extern int kgdb_isremovedbreak(unsigned long addr); + +extern int +kgdb_handle_exception(int ex_vector, int signo, int err_code, + struct pt_regs *regs); +extern int kgdb_nmicallback(int cpu, void *regs); + +extern int kgdb_single_step; +extern atomic_t kgdb_active; + +#endif /* _KGDB_H_ */ diff --git a/include/linux/libata.h b/include/linux/libata.h index b064bfeb69e..165734a2dd4 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -122,6 +122,8 @@ enum { ATAPI_MAX_DRAIN = 16 << 10, + ATA_ALL_DEVICES = (1 << ATA_MAX_DEVICES) - 1, + ATA_SHT_EMULATED = 1, ATA_SHT_CMD_PER_LUN = 1, ATA_SHT_THIS_ID = -1, @@ -163,9 +165,6 @@ enum { ATA_DEV_NONE = 9, /* no device */ /* struct ata_link flags */ - ATA_LFLAG_HRST_TO_RESUME = (1 << 0), /* hardreset to resume link */ - ATA_LFLAG_SKIP_D2H_BSY = (1 << 1), /* can't wait for the first D2H - * Register FIS clearing BSY */ ATA_LFLAG_NO_SRST = (1 << 2), /* avoid softreset */ ATA_LFLAG_ASSUME_ATA = (1 << 3), /* assume ATA class */ ATA_LFLAG_ASSUME_SEMB = (1 << 4), /* assume SEMB class */ @@ -225,6 +224,7 @@ enum { ATA_QCFLAG_RESULT_TF = (1 << 4), /* result TF requested */ ATA_QCFLAG_CLEAR_EXCL = (1 << 5), /* clear excl_link on completion */ ATA_QCFLAG_QUIET = (1 << 6), /* don't report device error */ + ATA_QCFLAG_RETRY = (1 << 7), /* retry after failure */ ATA_QCFLAG_FAILED = (1 << 16), /* cmd failed and is owned by EH */ ATA_QCFLAG_SENSE_VALID = (1 << 17), /* sense data valid */ @@ -249,6 +249,25 @@ enum { */ ATA_TMOUT_FF_WAIT = 4 * HZ / 5, + /* Spec mandates to wait for ">= 2ms" before checking status + * after reset. We wait 150ms, because that was the magic + * delay used for ATAPI devices in Hale Landis's ATADRVR, for + * the period of time between when the ATA command register is + * written, and then status is checked. Because waiting for + * "a while" before checking status is fine, post SRST, we + * perform this magic delay here as well. + * + * Old drivers/ide uses the 2mS rule and then waits for ready. + */ + ATA_WAIT_AFTER_RESET_MSECS = 150, + + /* If PMP is supported, we have to do follow-up SRST. As some + * PMPs don't send D2H Reg FIS after hardreset, LLDs are + * advised to wait only for the following duration before + * doing SRST. + */ + ATA_TMOUT_PMP_SRST_WAIT = 1 * HZ, + /* ATA bus states */ BUS_UNKNOWN = 0, BUS_DMA = 1, @@ -292,17 +311,16 @@ enum { /* reset / recovery action types */ ATA_EH_REVALIDATE = (1 << 0), - ATA_EH_SOFTRESET = (1 << 1), - ATA_EH_HARDRESET = (1 << 2), + ATA_EH_SOFTRESET = (1 << 1), /* meaningful only in ->prereset */ + ATA_EH_HARDRESET = (1 << 2), /* meaningful only in ->prereset */ + ATA_EH_RESET = ATA_EH_SOFTRESET | ATA_EH_HARDRESET, ATA_EH_ENABLE_LINK = (1 << 3), ATA_EH_LPM = (1 << 4), /* link power management action */ - ATA_EH_RESET_MASK = ATA_EH_SOFTRESET | ATA_EH_HARDRESET, ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE, /* ata_eh_info->flags */ ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */ - ATA_EHI_RESUME_LINK = (1 << 1), /* resume link (reset modifier) */ ATA_EHI_NO_AUTOPSY = (1 << 2), /* no autopsy */ ATA_EHI_QUIET = (1 << 3), /* be quiet */ @@ -313,7 +331,6 @@ enum { ATA_EHI_POST_SETMODE = (1 << 20), /* revaildating after setmode */ ATA_EHI_DID_RESET = ATA_EHI_DID_SOFTRESET | ATA_EHI_DID_HARDRESET, - ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK, /* max tries if error condition is still set after ->error_handler */ ATA_EH_MAX_TRIES = 5, @@ -350,7 +367,24 @@ enum { ATAPI_READ = 0, /* READs */ ATAPI_WRITE = 1, /* WRITEs */ ATAPI_READ_CD = 2, /* READ CD [MSF] */ - ATAPI_MISC = 3, /* the rest */ + ATAPI_PASS_THRU = 3, /* SAT pass-thru */ + ATAPI_MISC = 4, /* the rest */ + + /* Timing constants */ + ATA_TIMING_SETUP = (1 << 0), + ATA_TIMING_ACT8B = (1 << 1), + ATA_TIMING_REC8B = (1 << 2), + ATA_TIMING_CYC8B = (1 << 3), + ATA_TIMING_8BIT = ATA_TIMING_ACT8B | ATA_TIMING_REC8B | + ATA_TIMING_CYC8B, + ATA_TIMING_ACTIVE = (1 << 4), + ATA_TIMING_RECOVER = (1 << 5), + ATA_TIMING_CYCLE = (1 << 6), + ATA_TIMING_UDMA = (1 << 7), + ATA_TIMING_ALL = ATA_TIMING_SETUP | ATA_TIMING_ACT8B | + ATA_TIMING_REC8B | ATA_TIMING_CYC8B | + ATA_TIMING_ACTIVE | ATA_TIMING_RECOVER | + ATA_TIMING_CYCLE | ATA_TIMING_UDMA, }; enum ata_xfer_mask { @@ -411,6 +445,7 @@ enum link_pm { }; extern struct class_device_attribute class_device_attr_link_power_management_policy; +#ifdef CONFIG_ATA_SFF struct ata_ioports { void __iomem *cmd_addr; void __iomem *data_addr; @@ -428,6 +463,7 @@ struct ata_ioports { void __iomem *bmdma_addr; void __iomem *scr_addr; }; +#endif /* CONFIG_ATA_SFF */ struct ata_host { spinlock_t lock; @@ -435,7 +471,7 @@ struct ata_host { void __iomem * const *iomap; unsigned int n_ports; void *private_data; - const struct ata_port_operations *ops; + struct ata_port_operations *ops; unsigned long flags; #ifdef CONFIG_ATA_ACPI acpi_handle acpi_handle; @@ -604,7 +640,7 @@ struct ata_link { struct ata_port { struct Scsi_Host *scsi_host; /* our co-allocated scsi host */ - const struct ata_port_operations *ops; + struct ata_port_operations *ops; spinlock_t *lock; unsigned long flags; /* ATA_FLAG_xxx */ unsigned int pflags; /* ATA_PFLAG_xxx */ @@ -614,7 +650,9 @@ struct ata_port { struct ata_prd *prd; /* our SG list */ dma_addr_t prd_dma; /* and its DMA mapping */ +#ifdef CONFIG_ATA_SFF struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */ +#endif /* CONFIG_ATA_SFF */ u8 ctl; /* cache of ATA control register */ u8 last_ctl; /* Cache last written value */ @@ -666,81 +704,108 @@ struct ata_port { u8 sector_buf[ATA_SECT_SIZE]; /* owned by EH */ }; -struct ata_port_operations { - void (*dev_config) (struct ata_device *); - - void (*set_piomode) (struct ata_port *, struct ata_device *); - void (*set_dmamode) (struct ata_port *, struct ata_device *); - unsigned long (*mode_filter) (struct ata_device *, unsigned long); - - void (*tf_load) (struct ata_port *ap, const struct ata_taskfile *tf); - void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf); - - void (*exec_command)(struct ata_port *ap, const struct ata_taskfile *tf); - u8 (*check_status)(struct ata_port *ap); - u8 (*check_altstatus)(struct ata_port *ap); - void (*dev_select)(struct ata_port *ap, unsigned int device); - - void (*phy_reset) (struct ata_port *ap); /* obsolete */ - int (*set_mode) (struct ata_link *link, struct ata_device **r_failed_dev); - - int (*cable_detect) (struct ata_port *ap); - - int (*check_atapi_dma) (struct ata_queued_cmd *qc); - - void (*bmdma_setup) (struct ata_queued_cmd *qc); - void (*bmdma_start) (struct ata_queued_cmd *qc); - - unsigned int (*data_xfer) (struct ata_device *dev, unsigned char *buf, - unsigned int buflen, int rw); - - int (*qc_defer) (struct ata_queued_cmd *qc); - void (*qc_prep) (struct ata_queued_cmd *qc); - unsigned int (*qc_issue) (struct ata_queued_cmd *qc); - - /* port multiplier */ - void (*pmp_attach) (struct ata_port *ap); - void (*pmp_detach) (struct ata_port *ap); +/* The following initializer overrides a method to NULL whether one of + * its parent has the method defined or not. This is equivalent to + * ERR_PTR(-ENOENT). Unfortunately, ERR_PTR doesn't render a constant + * expression and thus can't be used as an initializer. + */ +#define ATA_OP_NULL (void *)(unsigned long)(-ENOENT) - /* Error handlers. ->error_handler overrides ->eng_timeout and - * indicates that new-style EH is in place. +struct ata_port_operations { + /* + * Command execution */ - void (*eng_timeout) (struct ata_port *ap); /* obsolete */ - - void (*freeze) (struct ata_port *ap); - void (*thaw) (struct ata_port *ap); - void (*error_handler) (struct ata_port *ap); - void (*post_internal_cmd) (struct ata_queued_cmd *qc); - - irq_handler_t irq_handler; - void (*irq_clear) (struct ata_port *); - u8 (*irq_on) (struct ata_port *); - - int (*scr_read) (struct ata_port *ap, unsigned int sc_reg, u32 *val); - int (*scr_write) (struct ata_port *ap, unsigned int sc_reg, u32 val); + int (*qc_defer)(struct ata_queued_cmd *qc); + int (*check_atapi_dma)(struct ata_queued_cmd *qc); + void (*qc_prep)(struct ata_queued_cmd *qc); + unsigned int (*qc_issue)(struct ata_queued_cmd *qc); + bool (*qc_fill_rtf)(struct ata_queued_cmd *qc); + + /* + * Configuration and exception handling + */ + int (*cable_detect)(struct ata_port *ap); + unsigned long (*mode_filter)(struct ata_device *dev, unsigned long xfer_mask); + void (*set_piomode)(struct ata_port *ap, struct ata_device *dev); + void (*set_dmamode)(struct ata_port *ap, struct ata_device *dev); + int (*set_mode)(struct ata_link *link, struct ata_device **r_failed_dev); + + void (*dev_config)(struct ata_device *dev); + + void (*freeze)(struct ata_port *ap); + void (*thaw)(struct ata_port *ap); + ata_prereset_fn_t prereset; + ata_reset_fn_t softreset; + ata_reset_fn_t hardreset; + ata_postreset_fn_t postreset; + ata_prereset_fn_t pmp_prereset; + ata_reset_fn_t pmp_softreset; + ata_reset_fn_t pmp_hardreset; + ata_postreset_fn_t pmp_postreset; + void (*error_handler)(struct ata_port *ap); + void (*post_internal_cmd)(struct ata_queued_cmd *qc); + + /* + * Optional features + */ + int (*scr_read)(struct ata_port *ap, unsigned int sc_reg, u32 *val); + int (*scr_write)(struct ata_port *ap, unsigned int sc_reg, u32 val); + void (*pmp_attach)(struct ata_port *ap); + void (*pmp_detach)(struct ata_port *ap); + int (*enable_pm)(struct ata_port *ap, enum link_pm policy); + void (*disable_pm)(struct ata_port *ap); + + /* + * Start, stop, suspend and resume + */ + int (*port_suspend)(struct ata_port *ap, pm_message_t mesg); + int (*port_resume)(struct ata_port *ap); + int (*port_start)(struct ata_port *ap); + void (*port_stop)(struct ata_port *ap); + void (*host_stop)(struct ata_host *host); + +#ifdef CONFIG_ATA_SFF + /* + * SFF / taskfile oriented ops + */ + void (*sff_dev_select)(struct ata_port *ap, unsigned int device); + u8 (*sff_check_status)(struct ata_port *ap); + u8 (*sff_check_altstatus)(struct ata_port *ap); + void (*sff_tf_load)(struct ata_port *ap, const struct ata_taskfile *tf); + void (*sff_tf_read)(struct ata_port *ap, struct ata_taskfile *tf); + void (*sff_exec_command)(struct ata_port *ap, + const struct ata_taskfile *tf); + unsigned int (*sff_data_xfer)(struct ata_device *dev, + unsigned char *buf, unsigned int buflen, int rw); + u8 (*sff_irq_on)(struct ata_port *); + void (*sff_irq_clear)(struct ata_port *); - int (*port_suspend) (struct ata_port *ap, pm_message_t mesg); - int (*port_resume) (struct ata_port *ap); - int (*enable_pm) (struct ata_port *ap, enum link_pm policy); - void (*disable_pm) (struct ata_port *ap); - int (*port_start) (struct ata_port *ap); - void (*port_stop) (struct ata_port *ap); + void (*bmdma_setup)(struct ata_queued_cmd *qc); + void (*bmdma_start)(struct ata_queued_cmd *qc); + void (*bmdma_stop)(struct ata_queued_cmd *qc); + u8 (*bmdma_status)(struct ata_port *ap); +#endif /* CONFIG_ATA_SFF */ - void (*host_stop) (struct ata_host *host); + /* + * Obsolete + */ + void (*phy_reset)(struct ata_port *ap); + void (*eng_timeout)(struct ata_port *ap); - void (*bmdma_stop) (struct ata_queued_cmd *qc); - u8 (*bmdma_status) (struct ata_port *ap); + /* + * ->inherits must be the last field and all the preceding + * fields must be pointers. + */ + const struct ata_port_operations *inherits; }; struct ata_port_info { - struct scsi_host_template *sht; unsigned long flags; unsigned long link_flags; unsigned long pio_mask; unsigned long mwdma_mask; unsigned long udma_mask; - const struct ata_port_operations *port_ops; - irq_handler_t irq_handler; + struct ata_port_operations *port_ops; void *private_data; }; @@ -758,11 +823,14 @@ struct ata_timing { #define FIT(v, vmin, vmax) max_t(short, min_t(short, v, vmax), vmin) +/* + * Core layer - drivers/ata/libata-core.c + */ extern const unsigned long sata_deb_timing_normal[]; extern const unsigned long sata_deb_timing_hotplug[]; extern const unsigned long sata_deb_timing_long[]; -extern const struct ata_port_operations ata_dummy_port_ops; +extern struct ata_port_operations ata_dummy_port_ops; extern const struct ata_port_info ata_dummy_port_info; static inline const unsigned long * @@ -781,22 +849,21 @@ static inline int ata_port_is_dummy(struct ata_port *ap) extern void sata_print_link_status(struct ata_link *link); extern void ata_port_probe(struct ata_port *); -extern void ata_bus_reset(struct ata_port *ap); extern int sata_set_spd(struct ata_link *link); +extern int ata_std_prereset(struct ata_link *link, unsigned long deadline); +extern int ata_wait_after_reset(struct ata_link *link, unsigned long deadline, + int (*check_ready)(struct ata_link *link)); extern int sata_link_debounce(struct ata_link *link, const unsigned long *params, unsigned long deadline); extern int sata_link_resume(struct ata_link *link, const unsigned long *params, unsigned long deadline); -extern int ata_std_prereset(struct ata_link *link, unsigned long deadline); -extern int ata_std_softreset(struct ata_link *link, unsigned int *classes, - unsigned long deadline); extern int sata_link_hardreset(struct ata_link *link, - const unsigned long *timing, unsigned long deadline); + const unsigned long *timing, unsigned long deadline, + bool *online, int (*check_ready)(struct ata_link *)); extern int sata_std_hardreset(struct ata_link *link, unsigned int *class, unsigned long deadline); extern void ata_std_postreset(struct ata_link *link, unsigned int *classes); extern void ata_port_disable(struct ata_port *); -extern void ata_std_ports(struct ata_ioports *ioaddr); extern struct ata_host *ata_host_alloc(struct device *dev, int max_ports); extern struct ata_host *ata_host_alloc_pinfo(struct device *dev, @@ -809,7 +876,7 @@ extern int ata_host_activate(struct ata_host *host, int irq, struct scsi_host_template *sht); extern void ata_host_detach(struct ata_host *host); extern void ata_host_init(struct ata_host *, struct device *, - unsigned long, const struct ata_port_operations *); + unsigned long, struct ata_port_operations *); extern int ata_scsi_detect(struct scsi_host_template *sht); extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); @@ -822,7 +889,6 @@ extern void ata_sas_port_stop(struct ata_port *ap); extern int ata_sas_slave_configure(struct scsi_device *, struct ata_port *); extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *), struct ata_port *ap); -extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); extern int sata_scr_valid(struct ata_link *link); extern int sata_scr_read(struct ata_link *link, int reg, u32 *val); extern int sata_scr_write(struct ata_link *link, int reg, u32 val); @@ -834,21 +900,10 @@ extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg); extern void ata_host_resume(struct ata_host *host); #endif extern int ata_ratelimit(void); -extern int ata_busy_sleep(struct ata_port *ap, - unsigned long timeout_pat, unsigned long timeout); -extern void ata_wait_after_reset(struct ata_port *ap, unsigned long deadline); -extern int ata_wait_ready(struct ata_port *ap, unsigned long deadline); extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, unsigned long interval_msec, unsigned long timeout_msec); -extern unsigned int ata_dev_try_classify(struct ata_device *dev, int present, - u8 *r_err); - -/* - * Default driver ops implementations - */ -extern void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf); -extern void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf); +extern int atapi_cmd_type(u8 opcode); extern void ata_tf_to_fis(const struct ata_taskfile *tf, u8 pmp, int is_cmd, u8 *fis); extern void ata_tf_from_fis(const u8 *fis, struct ata_taskfile *tf); @@ -862,23 +917,9 @@ extern unsigned long ata_xfer_mode2mask(u8 xfer_mode); extern int ata_xfer_mode2shift(unsigned long xfer_mode); extern const char *ata_mode_string(unsigned long xfer_mask); extern unsigned long ata_id_xfermask(const u16 *id); -extern void ata_noop_dev_select(struct ata_port *ap, unsigned int device); -extern void ata_std_dev_select(struct ata_port *ap, unsigned int device); -extern u8 ata_check_status(struct ata_port *ap); -extern u8 ata_altstatus(struct ata_port *ap); -extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf); extern int ata_port_start(struct ata_port *ap); -extern int ata_sff_port_start(struct ata_port *ap); -extern irqreturn_t ata_interrupt(int irq, void *dev_instance); -extern unsigned int ata_data_xfer(struct ata_device *dev, - unsigned char *buf, unsigned int buflen, int rw); -extern unsigned int ata_data_xfer_noirq(struct ata_device *dev, - unsigned char *buf, unsigned int buflen, int rw); extern int ata_std_qc_defer(struct ata_queued_cmd *qc); -extern void ata_dumb_qc_prep(struct ata_queued_cmd *qc); -extern void ata_qc_prep(struct ata_queued_cmd *qc); extern void ata_noop_qc_prep(struct ata_queued_cmd *qc); -extern unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc); extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, unsigned int n_elem); extern unsigned int ata_dev_classify(const struct ata_taskfile *tf); @@ -887,24 +928,8 @@ extern void ata_id_string(const u16 *id, unsigned char *s, unsigned int ofs, unsigned int len); extern void ata_id_c_string(const u16 *id, unsigned char *s, unsigned int ofs, unsigned int len); -extern void ata_bmdma_setup(struct ata_queued_cmd *qc); -extern void ata_bmdma_start(struct ata_queued_cmd *qc); -extern void ata_bmdma_stop(struct ata_queued_cmd *qc); -extern u8 ata_bmdma_status(struct ata_port *ap); -extern void ata_bmdma_irq_clear(struct ata_port *ap); -extern void ata_bmdma_freeze(struct ata_port *ap); -extern void ata_bmdma_thaw(struct ata_port *ap); -extern void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset, - ata_reset_fn_t softreset, - ata_reset_fn_t hardreset, - ata_postreset_fn_t postreset); -extern void ata_bmdma_error_handler(struct ata_port *ap); -extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc); -extern int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, - u8 status, int in_wq); extern void ata_qc_complete(struct ata_queued_cmd *qc); -extern int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active, - void (*finish_qc)(struct ata_queued_cmd *)); +extern int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active); extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); extern int ata_std_bios_param(struct scsi_device *sdev, @@ -916,7 +941,6 @@ extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth); extern struct ata_device *ata_dev_pair(struct ata_device *adev); extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev); -extern u8 ata_irq_on(struct ata_port *ap); extern int ata_cable_40wire(struct ata_port *ap); extern int ata_cable_80wire(struct ata_port *ap); @@ -924,10 +948,7 @@ extern int ata_cable_sata(struct ata_port *ap); extern int ata_cable_ignore(struct ata_port *ap); extern int ata_cable_unknown(struct ata_port *ap); -/* - * Timing helpers - */ - +/* Timing helpers */ extern unsigned int ata_pio_need_iordy(const struct ata_device *); extern const struct ata_timing *ata_timing_find_mode(u8 xfer_mode); extern int ata_timing_compute(struct ata_device *, unsigned short, @@ -937,24 +958,31 @@ extern void ata_timing_merge(const struct ata_timing *, unsigned int); extern u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle); -enum { - ATA_TIMING_SETUP = (1 << 0), - ATA_TIMING_ACT8B = (1 << 1), - ATA_TIMING_REC8B = (1 << 2), - ATA_TIMING_CYC8B = (1 << 3), - ATA_TIMING_8BIT = ATA_TIMING_ACT8B | ATA_TIMING_REC8B | - ATA_TIMING_CYC8B, - ATA_TIMING_ACTIVE = (1 << 4), - ATA_TIMING_RECOVER = (1 << 5), - ATA_TIMING_CYCLE = (1 << 6), - ATA_TIMING_UDMA = (1 << 7), - ATA_TIMING_ALL = ATA_TIMING_SETUP | ATA_TIMING_ACT8B | - ATA_TIMING_REC8B | ATA_TIMING_CYC8B | - ATA_TIMING_ACTIVE | ATA_TIMING_RECOVER | - ATA_TIMING_CYCLE | ATA_TIMING_UDMA, +/* PCI */ +#ifdef CONFIG_PCI +struct pci_dev; + +struct pci_bits { + unsigned int reg; /* PCI config register to read */ + unsigned int width; /* 1 (8 bit), 2 (16 bit), 4 (32 bit) */ + unsigned long mask; + unsigned long val; }; -/* libata-acpi.c */ +extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits); +extern void ata_pci_remove_one(struct pci_dev *pdev); + +#ifdef CONFIG_PM +extern void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg); +extern int __must_check ata_pci_device_do_resume(struct pci_dev *pdev); +extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); +extern int ata_pci_device_resume(struct pci_dev *pdev); +#endif /* CONFIG_PM */ +#endif /* CONFIG_PCI */ + +/* + * ACPI - drivers/ata/libata-acpi.c + */ #ifdef CONFIG_ATA_ACPI static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap) { @@ -998,56 +1026,8 @@ static inline int ata_acpi_cbl_80wire(struct ata_port *ap, } #endif -#ifdef CONFIG_PCI -struct pci_dev; - -extern int ata_pci_init_one(struct pci_dev *pdev, - const struct ata_port_info * const * ppi); -extern void ata_pci_remove_one(struct pci_dev *pdev); -#ifdef CONFIG_PM -extern void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg); -extern int __must_check ata_pci_device_do_resume(struct pci_dev *pdev); -extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg); -extern int ata_pci_device_resume(struct pci_dev *pdev); -#endif -extern int ata_pci_clear_simplex(struct pci_dev *pdev); - -struct pci_bits { - unsigned int reg; /* PCI config register to read */ - unsigned int width; /* 1 (8 bit), 2 (16 bit), 4 (32 bit) */ - unsigned long mask; - unsigned long val; -}; - -extern int ata_pci_init_sff_host(struct ata_host *host); -extern int ata_pci_init_bmdma(struct ata_host *host); -extern int ata_pci_prepare_sff_host(struct pci_dev *pdev, - const struct ata_port_info * const * ppi, - struct ata_host **r_host); -extern int ata_pci_activate_sff_host(struct ata_host *host, - irq_handler_t irq_handler, - struct scsi_host_template *sht); -extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits); -extern unsigned long ata_pci_default_filter(struct ata_device *dev, - unsigned long xfer_mask); -#endif /* CONFIG_PCI */ - -/* - * PMP - */ -extern int sata_pmp_qc_defer_cmd_switch(struct ata_queued_cmd *qc); -extern int sata_pmp_std_prereset(struct ata_link *link, unsigned long deadline); -extern int sata_pmp_std_hardreset(struct ata_link *link, unsigned int *class, - unsigned long deadline); -extern void sata_pmp_std_postreset(struct ata_link *link, unsigned int *class); -extern void sata_pmp_do_eh(struct ata_port *ap, - ata_prereset_fn_t prereset, ata_reset_fn_t softreset, - ata_reset_fn_t hardreset, ata_postreset_fn_t postreset, - ata_prereset_fn_t pmp_prereset, ata_reset_fn_t pmp_softreset, - ata_reset_fn_t pmp_hardreset, ata_postreset_fn_t pmp_postreset); - /* - * EH + * EH - drivers/ata/libata-eh.c */ extern void ata_port_schedule_eh(struct ata_port *ap); extern int ata_link_abort(struct ata_link *link); @@ -1064,6 +1044,92 @@ extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, ata_postreset_fn_t postreset); +extern void ata_std_error_handler(struct ata_port *ap); + +/* + * Base operations to inherit from and initializers for sht + * + * Operations + * + * base : Common to all libata drivers. + * sata : SATA controllers w/ native interface. + * pmp : SATA controllers w/ PMP support. + * sff : SFF ATA controllers w/o BMDMA support. + * bmdma : SFF ATA controllers w/ BMDMA support. + * + * sht initializers + * + * BASE : Common to all libata drivers. The user must set + * sg_tablesize and dma_boundary. + * PIO : SFF ATA controllers w/ only PIO support. + * BMDMA : SFF ATA controllers w/ BMDMA support. sg_tablesize and + * dma_boundary are set to BMDMA limits. + * NCQ : SATA controllers supporting NCQ. The user must set + * sg_tablesize, dma_boundary and can_queue. + */ +extern const struct ata_port_operations ata_base_port_ops; +extern const struct ata_port_operations sata_port_ops; + +#define ATA_BASE_SHT(drv_name) \ + .module = THIS_MODULE, \ + .name = drv_name, \ + .ioctl = ata_scsi_ioctl, \ + .queuecommand = ata_scsi_queuecmd, \ + .can_queue = ATA_DEF_QUEUE, \ + .this_id = ATA_SHT_THIS_ID, \ + .cmd_per_lun = ATA_SHT_CMD_PER_LUN, \ + .emulated = ATA_SHT_EMULATED, \ + .use_clustering = ATA_SHT_USE_CLUSTERING, \ + .proc_name = drv_name, \ + .slave_configure = ata_scsi_slave_config, \ + .slave_destroy = ata_scsi_slave_destroy, \ + .bios_param = ata_std_bios_param + +#define ATA_NCQ_SHT(drv_name) \ + ATA_BASE_SHT(drv_name), \ + .change_queue_depth = ata_scsi_change_queue_depth + +/* + * PMP helpers + */ +#ifdef CONFIG_SATA_PMP +static inline bool sata_pmp_supported(struct ata_port *ap) +{ + return ap->flags & ATA_FLAG_PMP; +} + +static inline bool sata_pmp_attached(struct ata_port *ap) +{ + return ap->nr_pmp_links != 0; +} + +static inline int ata_is_host_link(const struct ata_link *link) +{ + return link == &link->ap->link; +} +#else /* CONFIG_SATA_PMP */ +static inline bool sata_pmp_supported(struct ata_port *ap) +{ + return false; +} + +static inline bool sata_pmp_attached(struct ata_port *ap) +{ + return false; +} + +static inline int ata_is_host_link(const struct ata_link *link) +{ + return 1; +} +#endif /* CONFIG_SATA_PMP */ + +static inline int sata_srst_pmp(struct ata_link *link) +{ + if (sata_pmp_supported(link->ap) && ata_is_host_link(link)) + return SATA_PMP_CTRL_PORT; + return link->pmp; +} /* * printk helpers @@ -1072,7 +1138,7 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, printk("%sata%u: "fmt, lv, (ap)->print_id , ##args) #define ata_link_printk(link, lv, fmt, args...) do { \ - if ((link)->ap->nr_pmp_links) \ + if (sata_pmp_attached((link)->ap)) \ printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \ (link)->pmp , ##args); \ else \ @@ -1092,18 +1158,11 @@ extern void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); extern void ata_ehi_clear_desc(struct ata_eh_info *ehi); -static inline void ata_ehi_schedule_probe(struct ata_eh_info *ehi) -{ - ehi->flags |= ATA_EHI_RESUME_LINK; - ehi->action |= ATA_EH_SOFTRESET; - ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1; -} - static inline void ata_ehi_hotplugged(struct ata_eh_info *ehi) { - ata_ehi_schedule_probe(ehi); + ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1; ehi->flags |= ATA_EHI_HOTPLUGGED; - ehi->action |= ATA_EH_ENABLE_LINK; + ehi->action |= ATA_EH_RESET | ATA_EH_ENABLE_LINK; ehi->err_mask |= AC_ERR_ATA_BUS; } @@ -1124,7 +1183,7 @@ static inline unsigned int ata_tag_valid(unsigned int tag) static inline unsigned int ata_tag_internal(unsigned int tag) { - return tag == ATA_MAX_QUEUE - 1; + return tag == ATA_TAG_INTERNAL; } /* @@ -1165,11 +1224,6 @@ static inline unsigned int ata_dev_absent(const struct ata_device *dev) /* * link helpers */ -static inline int ata_is_host_link(const struct ata_link *link) -{ - return link == &link->ap->link; -} - static inline int ata_link_max_devices(const struct ata_link *link) { if (ata_is_host_link(link) && link->ap->flags & ATA_FLAG_SLAVE_POSS) @@ -1184,7 +1238,7 @@ static inline int ata_link_active(struct ata_link *link) static inline struct ata_link *ata_port_first_link(struct ata_port *ap) { - if (ap->nr_pmp_links) + if (sata_pmp_attached(ap)) return ap->pmp_link; return &ap->link; } @@ -1193,8 +1247,8 @@ static inline struct ata_link *ata_port_next_link(struct ata_link *link) { struct ata_port *ap = link->ap; - if (link == &ap->link) { - if (!ap->nr_pmp_links) + if (ata_is_host_link(link)) { + if (!sata_pmp_attached(ap)) return NULL; return ap->pmp_link; } @@ -1220,11 +1274,6 @@ static inline struct ata_link *ata_port_next_link(struct ata_link *link) for ((dev) = (link)->device + ata_link_max_devices(link) - 1; \ (dev) >= (link)->device || ((dev) = NULL); (dev)--) -static inline u8 ata_chk_status(struct ata_port *ap) -{ - return ap->ops->check_status(ap); -} - /** * ata_ncq_enabled - Test whether NCQ is enabled * @dev: ATA device to test for @@ -1241,74 +1290,6 @@ static inline int ata_ncq_enabled(struct ata_device *dev) ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ; } -/** - * ata_pause - Flush writes and pause 400 nanoseconds. - * @ap: Port to wait for. - * - * LOCKING: - * Inherited from caller. - */ - -static inline void ata_pause(struct ata_port *ap) -{ - ata_altstatus(ap); - ndelay(400); -} - - -/** - * ata_busy_wait - Wait for a port status register - * @ap: Port to wait for. - * @bits: bits that must be clear - * @max: number of 10uS waits to perform - * - * Waits up to max*10 microseconds for the selected bits in the port's - * status register to be cleared. - * Returns final value of status register. - * - * LOCKING: - * Inherited from caller. - */ - -static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits, - unsigned int max) -{ - u8 status; - - do { - udelay(10); - status = ata_chk_status(ap); - max--; - } while (status != 0xff && (status & bits) && (max > 0)); - - return status; -} - - -/** - * ata_wait_idle - Wait for a port to be idle. - * @ap: Port to wait for. - * - * Waits up to 10ms for port's BUSY and DRQ signals to clear. - * Returns final value of status register. - * - * LOCKING: - * Inherited from caller. - */ - -static inline u8 ata_wait_idle(struct ata_port *ap) -{ - u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); - -#ifdef ATA_DEBUG - if (status != 0xff && (status & (ATA_BUSY | ATA_DRQ))) - ata_port_printk(ap, KERN_DEBUG, "abnormal Status 0x%X\n", - status); -#endif - - return status; -} - static inline void ata_qc_set_polling(struct ata_queued_cmd *qc) { qc->tf.ctl |= ATA_NIEN; @@ -1379,27 +1360,6 @@ static inline int ata_try_flush_cache(const struct ata_device *dev) ata_id_has_flush_ext(dev->id); } -static inline int atapi_cmd_type(u8 opcode) -{ - switch (opcode) { - case GPCMD_READ_10: - case GPCMD_READ_12: - return ATAPI_READ; - - case GPCMD_WRITE_10: - case GPCMD_WRITE_12: - case GPCMD_WRITE_AND_VERIFY_10: - return ATAPI_WRITE; - - case GPCMD_READ_CD: - case GPCMD_READ_CD_MSF: - return ATAPI_READ_CD; - - default: - return ATAPI_MISC; - } -} - static inline unsigned int ac_err_mask(u8 status) { if (status & (ATA_BUSY | ATA_DRQ)) @@ -1422,4 +1382,171 @@ static inline struct ata_port *ata_shost_to_port(struct Scsi_Host *host) return *(struct ata_port **)&host->hostdata[0]; } + +/************************************************************************** + * PMP - drivers/ata/libata-pmp.c + */ +#ifdef CONFIG_SATA_PMP + +extern const struct ata_port_operations sata_pmp_port_ops; + +extern int sata_pmp_qc_defer_cmd_switch(struct ata_queued_cmd *qc); +extern void sata_pmp_error_handler(struct ata_port *ap); + +#else /* CONFIG_SATA_PMP */ + +#define sata_pmp_port_ops sata_port_ops +#define sata_pmp_qc_defer_cmd_switch ata_std_qc_defer +#define sata_pmp_error_handler ata_std_error_handler + +#endif /* CONFIG_SATA_PMP */ + + +/************************************************************************** + * SFF - drivers/ata/libata-sff.c + */ +#ifdef CONFIG_ATA_SFF + +extern const struct ata_port_operations ata_sff_port_ops; +extern const struct ata_port_operations ata_bmdma_port_ops; + +/* PIO only, sg_tablesize and dma_boundary limits can be removed */ +#define ATA_PIO_SHT(drv_name) \ + ATA_BASE_SHT(drv_name), \ + .sg_tablesize = LIBATA_MAX_PRD, \ + .dma_boundary = ATA_DMA_BOUNDARY + +#define ATA_BMDMA_SHT(drv_name) \ + ATA_BASE_SHT(drv_name), \ + .sg_tablesize = LIBATA_MAX_PRD, \ + .dma_boundary = ATA_DMA_BOUNDARY + +extern void ata_sff_qc_prep(struct ata_queued_cmd *qc); +extern void ata_sff_dumb_qc_prep(struct ata_queued_cmd *qc); +extern void ata_sff_dev_select(struct ata_port *ap, unsigned int device); +extern u8 ata_sff_check_status(struct ata_port *ap); +extern u8 ata_sff_altstatus(struct ata_port *ap); +extern int ata_sff_busy_sleep(struct ata_port *ap, + unsigned long timeout_pat, unsigned long timeout); +extern int ata_sff_wait_ready(struct ata_link *link, unsigned long deadline); +extern void ata_sff_tf_load(struct ata_port *ap, const struct ata_taskfile *tf); +extern void ata_sff_tf_read(struct ata_port *ap, struct ata_taskfile *tf); +extern void ata_sff_exec_command(struct ata_port *ap, + const struct ata_taskfile *tf); +extern unsigned int ata_sff_data_xfer(struct ata_device *dev, + unsigned char *buf, unsigned int buflen, int rw); +extern unsigned int ata_sff_data_xfer_noirq(struct ata_device *dev, + unsigned char *buf, unsigned int buflen, int rw); +extern u8 ata_sff_irq_on(struct ata_port *ap); +extern void ata_sff_irq_clear(struct ata_port *ap); +extern int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, + u8 status, int in_wq); +extern unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc); +extern bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc); +extern unsigned int ata_sff_host_intr(struct ata_port *ap, + struct ata_queued_cmd *qc); +extern irqreturn_t ata_sff_interrupt(int irq, void *dev_instance); +extern void ata_sff_freeze(struct ata_port *ap); +extern void ata_sff_thaw(struct ata_port *ap); +extern int ata_sff_prereset(struct ata_link *link, unsigned long deadline); +extern unsigned int ata_sff_dev_classify(struct ata_device *dev, int present, + u8 *r_err); +extern int ata_sff_wait_after_reset(struct ata_link *link, unsigned int devmask, + unsigned long deadline); +extern int ata_sff_softreset(struct ata_link *link, unsigned int *classes, + unsigned long deadline); +extern int sata_sff_hardreset(struct ata_link *link, unsigned int *class, + unsigned long deadline); +extern void ata_sff_postreset(struct ata_link *link, unsigned int *classes); +extern void ata_sff_error_handler(struct ata_port *ap); +extern void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc); +extern int ata_sff_port_start(struct ata_port *ap); +extern void ata_sff_std_ports(struct ata_ioports *ioaddr); +extern unsigned long ata_bmdma_mode_filter(struct ata_device *dev, + unsigned long xfer_mask); +extern void ata_bmdma_setup(struct ata_queued_cmd *qc); +extern void ata_bmdma_start(struct ata_queued_cmd *qc); +extern void ata_bmdma_stop(struct ata_queued_cmd *qc); +extern u8 ata_bmdma_status(struct ata_port *ap); +extern void ata_bus_reset(struct ata_port *ap); + +#ifdef CONFIG_PCI +extern int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev); +extern int ata_pci_bmdma_init(struct ata_host *host); +extern int ata_pci_sff_init_host(struct ata_host *host); +extern int ata_pci_sff_prepare_host(struct pci_dev *pdev, + const struct ata_port_info * const * ppi, + struct ata_host **r_host); +extern int ata_pci_sff_activate_host(struct ata_host *host, + irq_handler_t irq_handler, + struct scsi_host_template *sht); +extern int ata_pci_sff_init_one(struct pci_dev *pdev, + const struct ata_port_info * const * ppi, + struct scsi_host_template *sht, void *host_priv); +#endif /* CONFIG_PCI */ + +/** + * ata_sff_pause - Flush writes and pause 400 nanoseconds. + * @ap: Port to wait for. + * + * LOCKING: + * Inherited from caller. + */ +static inline void ata_sff_pause(struct ata_port *ap) +{ + ata_sff_altstatus(ap); + ndelay(400); +} + +/** + * ata_sff_busy_wait - Wait for a port status register + * @ap: Port to wait for. + * @bits: bits that must be clear + * @max: number of 10uS waits to perform + * + * Waits up to max*10 microseconds for the selected bits in the port's + * status register to be cleared. + * Returns final value of status register. + * + * LOCKING: + * Inherited from caller. + */ +static inline u8 ata_sff_busy_wait(struct ata_port *ap, unsigned int bits, + unsigned int max) +{ + u8 status; + + do { + udelay(10); + status = ap->ops->sff_check_status(ap); + max--; + } while (status != 0xff && (status & bits) && (max > 0)); + + return status; +} + +/** + * ata_wait_idle - Wait for a port to be idle. + * @ap: Port to wait for. + * + * Waits up to 10ms for port's BUSY and DRQ signals to clear. + * Returns final value of status register. + * + * LOCKING: + * Inherited from caller. + */ +static inline u8 ata_wait_idle(struct ata_port *ap) +{ + u8 status = ata_sff_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); + +#ifdef ATA_DEBUG + if (status != 0xff && (status & (ATA_BUSY | ATA_DRQ))) + ata_port_printk(ap, KERN_DEBUG, "abnormal Status 0x%X\n", + status); +#endif + + return status; +} +#endif /* CONFIG_ATA_SFF */ + #endif /* __LINUX_LIBATA_H__ */ diff --git a/include/linux/linkage.h b/include/linux/linkage.h index 0592936344c..2119610b24f 100644 --- a/include/linux/linkage.h +++ b/include/linux/linkage.h @@ -17,8 +17,24 @@ # define asmregparm #endif -#ifndef prevent_tail_call -# define prevent_tail_call(ret) do { } while (0) +/* + * This is used by architectures to keep arguments on the stack + * untouched by the compiler by keeping them live until the end. + * The argument stack may be owned by the assembly-language + * caller, not the callee, and gcc doesn't always understand + * that. + * + * We have the return value, and a maximum of six arguments. + * + * This should always be followed by a "return ret" for the + * protection to work (ie no more work that the compiler might + * end up needing stack temporaries for). + */ +/* Assembly files may be compiled with -traditional .. */ +#ifndef __ASSEMBLY__ +#ifndef asmlinkage_protect +# define asmlinkage_protect(n, ret, args...) do { } while (0) +#endif #endif #ifndef __ALIGN diff --git a/include/linux/mbcache.h b/include/linux/mbcache.h index 99e044b4efc..a09b84e4fdb 100644 --- a/include/linux/mbcache.h +++ b/include/linux/mbcache.h @@ -34,7 +34,7 @@ void mb_cache_destroy(struct mb_cache *); /* Functions on cache entries */ -struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *); +struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *, gfp_t); int mb_cache_entry_insert(struct mb_cache_entry *, struct block_device *, sector_t, unsigned int[]); void mb_cache_entry_release(struct mb_cache_entry *); diff --git a/include/linux/mlx4/cmd.h b/include/linux/mlx4/cmd.h index 7d1eaa97de1..77323a72dd3 100644 --- a/include/linux/mlx4/cmd.h +++ b/include/linux/mlx4/cmd.h @@ -81,7 +81,7 @@ enum { MLX4_CMD_SW2HW_CQ = 0x16, MLX4_CMD_HW2SW_CQ = 0x17, MLX4_CMD_QUERY_CQ = 0x18, - MLX4_CMD_RESIZE_CQ = 0x2c, + MLX4_CMD_MODIFY_CQ = 0x2c, /* SRQ commands */ MLX4_CMD_SW2HW_SRQ = 0x35, diff --git a/include/linux/mlx4/cq.h b/include/linux/mlx4/cq.h index 0181e0a57cb..071cf96cf01 100644 --- a/include/linux/mlx4/cq.h +++ b/include/linux/mlx4/cq.h @@ -45,11 +45,11 @@ struct mlx4_cqe { u8 sl; u8 reserved1; __be16 rlid; - u32 reserved2; + __be32 ipoib_status; __be32 byte_cnt; __be16 wqe_index; __be16 checksum; - u8 reserved3[3]; + u8 reserved2[3]; u8 owner_sr_opcode; }; @@ -85,6 +85,16 @@ enum { MLX4_CQE_SYNDROME_REMOTE_ABORTED_ERR = 0x22, }; +enum { + MLX4_CQE_IPOIB_STATUS_IPV4 = 1 << 22, + MLX4_CQE_IPOIB_STATUS_IPV4F = 1 << 23, + MLX4_CQE_IPOIB_STATUS_IPV6 = 1 << 24, + MLX4_CQE_IPOIB_STATUS_IPV4OPT = 1 << 25, + MLX4_CQE_IPOIB_STATUS_TCP = 1 << 26, + MLX4_CQE_IPOIB_STATUS_UDP = 1 << 27, + MLX4_CQE_IPOIB_STATUS_IPOK = 1 << 28, +}; + static inline void mlx4_cq_arm(struct mlx4_cq *cq, u32 cmd, void __iomem *uar_page, spinlock_t *doorbell_lock) @@ -120,4 +130,9 @@ enum { MLX4_CQ_DB_REQ_NOT = 2 << 24 }; +int mlx4_cq_modify(struct mlx4_dev *dev, struct mlx4_cq *cq, + u16 count, u16 period); +int mlx4_cq_resize(struct mlx4_dev *dev, struct mlx4_cq *cq, + int entries, struct mlx4_mtt *mtt); + #endif /* MLX4_CQ_H */ diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 6cdf813cd47..ff7df1a2222 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -186,6 +186,7 @@ struct mlx4_caps { u32 flags; u16 stat_rate_support; u8 port_width_cap[MLX4_MAX_PORTS + 1]; + int max_gso_sz; }; struct mlx4_buf_list { diff --git a/include/linux/mlx4/driver.h b/include/linux/mlx4/driver.h index 1b835ca49df..53c5fdb6eac 100644 --- a/include/linux/mlx4/driver.h +++ b/include/linux/mlx4/driver.h @@ -48,8 +48,7 @@ struct mlx4_interface { void * (*add) (struct mlx4_dev *dev); void (*remove)(struct mlx4_dev *dev, void *context); void (*event) (struct mlx4_dev *dev, void *context, - enum mlx4_dev_event event, int subtype, - int port); + enum mlx4_dev_event event, int port); struct list_head list; }; diff --git a/include/linux/mlx4/qp.h b/include/linux/mlx4/qp.h index 09a2230923f..a5e43febee4 100644 --- a/include/linux/mlx4/qp.h +++ b/include/linux/mlx4/qp.h @@ -158,10 +158,12 @@ struct mlx4_qp_context { #define MLX4_FW_VER_WQE_CTRL_NEC mlx4_fw_ver(2, 2, 232) enum { - MLX4_WQE_CTRL_NEC = 1 << 29, - MLX4_WQE_CTRL_FENCE = 1 << 6, - MLX4_WQE_CTRL_CQ_UPDATE = 3 << 2, - MLX4_WQE_CTRL_SOLICITED = 1 << 1, + MLX4_WQE_CTRL_NEC = 1 << 29, + MLX4_WQE_CTRL_FENCE = 1 << 6, + MLX4_WQE_CTRL_CQ_UPDATE = 3 << 2, + MLX4_WQE_CTRL_SOLICITED = 1 << 1, + MLX4_WQE_CTRL_IP_CSUM = 1 << 4, + MLX4_WQE_CTRL_TCP_UDP_CSUM = 1 << 5, }; struct mlx4_wqe_ctrl_seg { @@ -217,6 +219,11 @@ struct mlx4_wqe_datagram_seg { __be32 reservd[2]; }; +struct mlx4_lso_seg { + __be32 mss_hdr_size; + __be32 header[0]; +}; + struct mlx4_wqe_bind_seg { __be32 flags1; __be32 flags2; diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index a2f003239c8..ee81906b516 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -383,9 +383,11 @@ static inline void __napi_complete(struct napi_struct *n) static inline void napi_complete(struct napi_struct *n) { - local_irq_disable(); + unsigned long flags; + + local_irq_save(flags); __napi_complete(n); - local_irq_enable(); + local_irq_restore(flags); } /** @@ -1072,12 +1074,14 @@ static inline int netif_is_multiqueue(const struct net_device *dev) } /* Use this variant when it is known for sure that it - * is executing from interrupt context. + * is executing from hardware interrupt context or with hardware interrupts + * disabled. */ extern void dev_kfree_skb_irq(struct sk_buff *skb); /* Use this variant in places where it could be invoked - * either from interrupt or non-interrupt context. + * from either hardware interrupt or other context, with hardware interrupts + * either disabled or enabled. */ extern void dev_kfree_skb_any(struct sk_buff *skb); diff --git a/include/linux/pnp.h b/include/linux/pnp.h index 29dd55838e8..b2f05c230f4 100644 --- a/include/linux/pnp.h +++ b/include/linux/pnp.h @@ -175,7 +175,7 @@ static inline void pnp_set_card_drvdata(struct pnp_card_link *pcard, void *data) struct pnp_dev { struct device dev; /* Driver Model device interface */ u64 dma_mask; - unsigned char number; /* used as an index, must be unique */ + unsigned int number; /* used as an index, must be unique */ int status; struct list_head global_list; /* node in global list of devices */ diff --git a/include/linux/quota.h b/include/linux/quota.h index 6e0393a5b2e..eb560d031ac 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h @@ -160,14 +160,18 @@ enum { #ifdef __KERNEL__ -#include <linux/spinlock.h> -#include <linux/rwsem.h> +#include <linux/list.h> #include <linux/mutex.h> +#include <linux/rwsem.h> +#include <linux/spinlock.h> +#include <linux/wait.h> #include <linux/dqblk_xfs.h> #include <linux/dqblk_v1.h> #include <linux/dqblk_v2.h> +#include <asm/atomic.h> + extern spinlock_t dq_data_lock; /* Maximal numbers of writes for quota operation (insert/delete/update) diff --git a/include/linux/semaphore.h b/include/linux/semaphore.h new file mode 100644 index 00000000000..9cae64b00d6 --- /dev/null +++ b/include/linux/semaphore.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2008 Intel Corporation + * Author: Matthew Wilcox <willy@linux.intel.com> + * + * Distributed under the terms of the GNU GPL, version 2 + * + * Please see kernel/semaphore.c for documentation of these functions + */ +#ifndef __LINUX_SEMAPHORE_H +#define __LINUX_SEMAPHORE_H + +#include <linux/list.h> +#include <linux/spinlock.h> + +/* Please don't access any members of this structure directly */ +struct semaphore { + spinlock_t lock; + unsigned int count; + struct list_head wait_list; +}; + +#define __SEMAPHORE_INITIALIZER(name, n) \ +{ \ + .lock = __SPIN_LOCK_UNLOCKED((name).lock), \ + .count = n, \ + .wait_list = LIST_HEAD_INIT((name).wait_list), \ +} + +#define __DECLARE_SEMAPHORE_GENERIC(name, count) \ + struct semaphore name = __SEMAPHORE_INITIALIZER(name, count) + +#define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name, 1) + +static inline void sema_init(struct semaphore *sem, int val) +{ + static struct lock_class_key __key; + *sem = (struct semaphore) __SEMAPHORE_INITIALIZER(*sem, val); + lockdep_init_map(&sem->lock.dep_map, "semaphore->lock", &__key, 0); +} + +#define init_MUTEX(sem) sema_init(sem, 1) +#define init_MUTEX_LOCKED(sem) sema_init(sem, 0) + +extern void down(struct semaphore *sem); +extern int __must_check down_interruptible(struct semaphore *sem); +extern int __must_check down_killable(struct semaphore *sem); +extern int __must_check down_trylock(struct semaphore *sem); +extern int __must_check down_timeout(struct semaphore *sem, long jiffies); +extern void up(struct semaphore *sem); + +#endif /* __LINUX_SEMAPHORE_H */ diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index 289942fc665..7cb094a8245 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -213,6 +213,10 @@ struct uart_ops { void (*config_port)(struct uart_port *, int); int (*verify_port)(struct uart_port *, struct serial_struct *); int (*ioctl)(struct uart_port *, unsigned int, unsigned long); +#ifdef CONFIG_CONSOLE_POLL + void (*poll_put_char)(struct uart_port *, unsigned char); + int (*poll_get_char)(struct uart_port *); +#endif }; #define UART_CONFIG_TYPE (1 << 0) diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index b00c1c73eb0..79d59c937fa 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h @@ -45,9 +45,9 @@ struct kmem_cache_cpu { struct kmem_cache_node { spinlock_t list_lock; /* Protect partial list and nr_partial */ unsigned long nr_partial; - atomic_long_t nr_slabs; struct list_head partial; #ifdef CONFIG_SLUB_DEBUG + atomic_long_t nr_slabs; struct list_head full; #endif }; diff --git a/include/linux/spinlock.h b/include/linux/spinlock.h index 576a5f77d3b..d311a090fae 100644 --- a/include/linux/spinlock.h +++ b/include/linux/spinlock.h @@ -296,43 +296,6 @@ do { \ }) /* - * Locks two spinlocks l1 and l2. - * l1_first indicates if spinlock l1 should be taken first. - */ -static inline void double_spin_lock(spinlock_t *l1, spinlock_t *l2, - bool l1_first) - __acquires(l1) - __acquires(l2) -{ - if (l1_first) { - spin_lock(l1); - spin_lock(l2); - } else { - spin_lock(l2); - spin_lock(l1); - } -} - -/* - * Unlocks two spinlocks l1 and l2. - * l1_taken_first indicates if spinlock l1 was taken first and therefore - * should be released after spinlock l2. - */ -static inline void double_spin_unlock(spinlock_t *l1, spinlock_t *l2, - bool l1_taken_first) - __releases(l1) - __releases(l2) -{ - if (l1_taken_first) { - spin_unlock(l2); - spin_unlock(l1); - } else { - spin_unlock(l1); - spin_unlock(l2); - } -} - -/* * Pull the atomic_t declaration: * (asm-mips/atomic.h needs above definitions) */ @@ -341,6 +304,9 @@ static inline void double_spin_unlock(spinlock_t *l1, spinlock_t *l2, * atomic_dec_and_lock - lock on reaching reference count zero * @atomic: the atomic counter * @lock: the spinlock in question + * + * Decrements @atomic by 1. If the result is 0, returns true and locks + * @lock. Returns false for all other cases. */ extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock); #define atomic_dec_and_lock(atomic, lock) \ diff --git a/include/linux/ssb/ssb.h b/include/linux/ssb/ssb.h index 20add65215a..db53defde5e 100644 --- a/include/linux/ssb/ssb.h +++ b/include/linux/ssb/ssb.h @@ -129,6 +129,10 @@ struct ssb_device { const struct ssb_bus_ops *ops; struct device *dev; + /* Pointer to the device that has to be used for + * any DMA related operation. */ + struct device *dma_dev; + struct ssb_bus *bus; struct ssb_device_id id; diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 818ca1cf0b6..90c1c191ea6 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -50,7 +50,7 @@ struct thermal_cooling_device_ops { }; #define THERMAL_TRIPS_NONE -1 -#define THERMAL_MAX_TRIPS 10 +#define THERMAL_MAX_TRIPS 12 #define THERMAL_NAME_LENGTH 20 struct thermal_cooling_device { int id; diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h index 421323e5a2d..accd7bad35b 100644 --- a/include/linux/thread_info.h +++ b/include/linux/thread_info.h @@ -9,6 +9,9 @@ #include <linux/types.h> +struct timespec; +struct compat_timespec; + /* * System call restart block. */ @@ -26,6 +29,15 @@ struct restart_block { u32 bitset; u64 time; } futex; + /* For nanosleep */ + struct { + clockid_t index; + struct timespec __user *rmtp; +#ifdef CONFIG_COMPAT + struct compat_timespec __user *compat_rmtp; +#endif + u64 expires; + } nanosleep; }; }; diff --git a/include/linux/tty_driver.h b/include/linux/tty_driver.h index 85c95cd39bc..21f69aca450 100644 --- a/include/linux/tty_driver.h +++ b/include/linux/tty_driver.h @@ -125,6 +125,7 @@ #include <linux/cdev.h> struct tty_struct; +struct tty_driver; struct tty_operations { int (*open)(struct tty_struct * tty, struct file * filp); @@ -157,6 +158,11 @@ struct tty_operations { int (*tiocmget)(struct tty_struct *tty, struct file *file); int (*tiocmset)(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); +#ifdef CONFIG_CONSOLE_POLL + int (*poll_init)(struct tty_driver *driver, int line, char *options); + int (*poll_get_char)(struct tty_driver *driver, int line); + void (*poll_put_char)(struct tty_driver *driver, int line, char ch); +#endif }; struct tty_driver { @@ -220,6 +226,11 @@ struct tty_driver { int (*tiocmget)(struct tty_struct *tty, struct file *file); int (*tiocmset)(struct tty_struct *tty, struct file *file, unsigned int set, unsigned int clear); +#ifdef CONFIG_CONSOLE_POLL + int (*poll_init)(struct tty_driver *driver, int line, char *options); + int (*poll_get_char)(struct tty_driver *driver, int line); + void (*poll_put_char)(struct tty_driver *driver, int line, char ch); +#endif struct list_head tty_drivers; }; @@ -230,6 +241,7 @@ struct tty_driver *alloc_tty_driver(int lines); void put_tty_driver(struct tty_driver *driver); void tty_set_operations(struct tty_driver *driver, const struct tty_operations *op); +extern struct tty_driver *tty_find_polling_driver(char *name, int *line); /* tty driver magic number */ #define TTY_DRIVER_MAGIC 0x5402 diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index 975c963e578..fec6decfb98 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -84,4 +84,26 @@ static inline unsigned long __copy_from_user_nocache(void *to, ret; \ }) +/* + * probe_kernel_read(): safely attempt to read from a location + * @dst: pointer to the buffer that shall take the data + * @src: address to read from + * @size: size of the data chunk + * + * Safely read from address @src to the buffer at @dst. If a kernel fault + * happens, handle that and return -EFAULT. + */ +extern long probe_kernel_read(void *dst, void *src, size_t size); + +/* + * probe_kernel_write(): safely attempt to write to a location + * @dst: address to write to + * @src: pointer to the data that shall be written + * @size: size of the data chunk + * + * Safely write to address @dst from the buffer at @src. If a kernel fault + * happens, handle that and return -EFAULT. + */ +extern long probe_kernel_write(void *dst, void *src, size_t size); + #endif /* __LINUX_UACCESS_H__ */ diff --git a/include/linux/virtio.h b/include/linux/virtio.h index 12c18ac1b97..e7d10845b3c 100644 --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -41,6 +41,8 @@ struct virtqueue * Returns NULL or the "data" token handed to add_buf. * @disable_cb: disable callbacks * vq: the struct virtqueue we're talking about. + * Note that this is not necessarily synchronous, hence unreliable and only + * useful as an optimization. * @enable_cb: restart callbacks after disable_cb. * vq: the struct virtqueue we're talking about. * This re-enables callbacks; it returns "false" if there are pending @@ -48,7 +50,8 @@ struct virtqueue * checking for more work, and enabling callbacks. * * Locking rules are straightforward: the driver is responsible for - * locking. No two operations may be invoked simultaneously. + * locking. No two operations may be invoked simultaneously, with the exception + * of @disable_cb. * * All operations can be called in any context. */ |