/* * Copyright (C) 2011 * Boaz Harrosh * * Public Declarations of the ORE API * * This file is part of the ORE (Object Raid Engine) library. * * ORE is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as published * by the Free Software Foundation. (GPL v2) * * ORE is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with the ORE; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef __ORE_H__ #define __ORE_H__ #include #include #include #include #include struct ore_comp { struct osd_obj_id obj; u8 cred[OSD_CAP_LEN]; }; struct ore_layout { /* Our way of looking at the data_map */ enum pnfs_osd_raid_algorithm4 raid_algorithm; unsigned stripe_unit; unsigned mirrors_p1; unsigned group_width; unsigned parity; u64 group_depth; unsigned group_count; /* Cached often needed calculations filled in by * ore_verify_layout */ unsigned long max_io_length; /* Max length that should be passed to * ore_get_rw_state */ }; struct ore_dev { struct osd_dev *od; }; struct ore_components { unsigned first_dev; /* First logical device no */ unsigned numdevs; /* Num of devices in array */ /* If @single_comp == EC_SINGLE_COMP, @comps points to a single * component. else there are @numdevs components */ enum EC_COMP_USAGE { EC_SINGLE_COMP = 0, EC_MULTPLE_COMPS = 0xffffffff } single_comp; struct ore_comp *comps; /* Array of pointers to ore_dev-* . User will usually have these pointed * too a bigger struct which contain an "ore_dev ored" member and use * container_of(oc->ods[i], struct foo_dev, ored) to access the bigger * structure. */ struct ore_dev **ods; }; /* ore_comp_dev Recievies a logical device index */ static inline struct osd_dev *ore_comp_dev( const struct ore_components *oc, unsigned i) { BUG_ON((i < oc->first_dev) || (oc->first_dev + oc->numdevs <= i)); return oc->ods[i - oc->first_dev]->od; } static inline void ore_comp_set_dev( struct ore_components *oc, unsigned i, struct osd_dev *od) { oc->ods[i - oc->first_dev]->od = od; } struct ore_striping_info { u64 offset; u64 obj_offset; u64 length; u64 first_stripe_start; /* only used in raid writes */ u64 M; /* for truncate */ unsigned bytes_in_stripe; unsigned dev; unsigned par_dev; unsigned unit_off; unsigned cur_pg; unsigned cur_comp; unsigned maxdevUnits; }; struct ore_io_state; typedef void (*ore_io_done_fn)(struct ore_io_state *ios, void *private); struct _ore_r4w_op { /* @Priv given here is passed ios->private */ struct page * (*get_page)(void *priv, u64 page_index, bool *uptodate); void (*put_page)(void *priv, struct page *page); }; struct ore_io_state { struct kref kref; struct ore_striping_info si; void *private; ore_io_done_fn done; struct ore_layout *layout; struct ore_components *oc; /* Global read/write IO*/ loff_t offset; unsigned long length; void *kern_buff; struct page **pages; unsigned nr_pages; unsigned pgbase; unsigned pages_consumed; /* Attributes */ unsigned in_attr_len; struct osd_attr *in_attr; unsigned out_attr_len; struct osd_attr *out_attr; bool reading; /* House keeping of Parity pages */ bool extra_part_alloc; struct page **parity_pages; unsigned max_par_pages; unsigned cur_par_page; unsigned sgs_per_dev; struct __stripe_pages_2d *sp2d; struct ore_io_state *ios_read_4_write; const struct _ore_r4w_op *r4w; /* Variable array of size numdevs */ unsigned numdevs; struct ore_per_dev_state { struct osd_request *or; struct bio *bio; loff_t offset; unsigned length; unsigned last_sgs_total; unsigned dev; struct osd_sg_entry *sglist; unsigned cur_sg; } per_dev[]; }; static inline unsigned ore_io_state_size(unsigned numdevs) { return sizeof(struct ore_io_state) + sizeof(struct ore_per_dev_state) * numdevs; } /* ore.c */ int ore_verify_layout(unsigned total_comps, struct ore_layout *layout); void ore_calc_stripe_info(struct ore_layout *layout, u64 file_offset, u64 length, struct ore_striping_info *si); int ore_get_rw_state(struct ore_layout *layout, struct ore_components *comps, bool is_reading, u64 offset, u64 length, struct ore_io_state **ios); int ore_get_io_state(struct ore_layout *layout, struct ore_components *comps, struct ore_io_state **ios); void ore_put_io_state(struct ore_io_state *ios); typedef void (*ore_on_dev_error)(struct ore_io_state *ios, struct ore_dev *od, unsigned dev_index, enum osd_err_priority oep, u64 dev_offset, u64 dev_len); int ore_check_io(struct ore_io_state *ios, ore_on_dev_error rep); int ore_create(struct ore_io_state *ios); int ore_remove(struct ore_io_state *ios); int ore_write(struct ore_io_state *ios); int ore_read(struct ore_io_state *ios); int ore_truncate(struct ore_layout *layout, struct ore_components *comps, u64 size); int extract_attr_from_ios(struct ore_io_state *ios, struct osd_attr *attr); extern const struct osd_attr g_attr_logical_length; #endif next.git/tree/include/uapi/mtd/Kbuild?id=ae4a3e028bb8b59e7cfeb0cc9ef03d885182ce8b'>include/uapi/mtd/Kbuild parent49def1853334396f948dcb4cedb9347abb318df5 (diff)
dmaengine: cppi41: Fix runtime PM timeouts with USB mass storage
Commit fdea2d09b997 ("dmaengine: cppi41: Add basic PM runtime support") added runtime PM support for cppi41, but had corner case issues. Some of the issues were fixed with commit 098de42ad670 ("dmaengine: cppi41: Fix unpaired pm runtime when only a USB hub is connected"). That fix however caused a new regression where we can get error -115 messages with USB on BeagleBone when connecting a USB mass storage device to a hub. This is because when connecting a USB mass storage device to a hub, the initial DMA transfers can take over 200ms to complete and cppi41 autosuspend delay times out. To fix the issue, we want to implement refcounting for chan_busy array that contains the active dma transfers. Increasing the autosuspend delay won't help as that the delay could be potentially seconds, and it's best to let the USB subsystem to deal with the timeouts on errors. The earlier attempt for runtime PM was buggy as the pm_runtime_get/put() calls could get unpaired easily as they did not follow the state of the chan_busy array as described in commit 098de42ad670 ("dmaengine: cppi41: Fix unpaired pm runtime when only a USB hub is connected". Let's fix the issue by adding pm_runtime_get() to where a new transfer is added to the chan_busy array, and calls to pm_runtime_put() where chan_busy array entry is cleared. This prevents any autosuspend timeouts from happening while dma transfers are active. Fixes: 098de42ad670 ("dmaengine: cppi41: Fix unpaired pm runtime when only a USB hub is connected") Fixes: fdea2d09b997 ("dmaengine: cppi41: Add basic PM runtime support") Cc: Andy Shevchenko <andy.shevchenko@gmail.com> Cc: Bin Liu <b-liu@ti.com> Cc: Grygorii Strashko <grygorii.strashko@ti.com> Cc: Kevin Hilman <khilman@baylibre.com> Cc: Patrick Titiano <ptitiano@baylibre.com> Cc: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> Signed-off-by: Tony Lindgren <tony@atomide.com> Tested-by: Bin Liu <b-liu@ti.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'include/uapi/mtd/Kbuild')