/*
 * Copyright (C) 2011
 * Boaz Harrosh <bharrosh@panasas.com>
 *
 * This file is part of the objects raid engine (ore).
 *
 * It 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with "ore". If not, write to the Free Software Foundation, Inc:
 *	"Free Software Foundation <info@fsf.org>"
 */

#include <linux/gfp.h>
#include <linux/async_tx.h>

#include "ore_raid.h"

#undef ORE_DBGMSG2
#define ORE_DBGMSG2 ORE_DBGMSG

struct page *_raid_page_alloc(void)
{
	return alloc_page(GFP_KERNEL);
}

void _raid_page_free(struct page *p)
{
	__free_page(p);
}

/* This struct is forward declare in ore_io_state, but is private to here.
 * It is put on ios->sp2d for RAID5/6 writes only. See _gen_xor_unit.
 *
 * __stripe_pages_2d is a 2d array of pages, and it is also a corner turn.
 * Ascending page index access is sp2d(p-minor, c-major). But storage is
 * sp2d[p-minor][c-major], so it can be properlly presented to the async-xor
 * API.
 */
struct __stripe_pages_2d {
	/* Cache some hot path repeated calculations */
	unsigned parity;
	unsigned data_devs;
	unsigned pages_in_unit;

	bool needed ;

	/* Array size is pages_in_unit (layout->stripe_unit / PAGE_SIZE) */
	struct __1_page_stripe {
		bool alloc;
		unsigned write_count;
		struct async_submit_ctl submit;
		struct dma_async_tx_descriptor *tx;

		/* The size of this array is data_devs + parity */
		struct page **pages;
		struct page **scribble;
		/* bool array, size of this array is data_devs */
		char *page_is_read;
	} _1p_stripes[];
};

/* This can get bigger then a page. So support multiple page allocations
 * _sp2d_free should be called even if _sp2d_alloc fails (by returning
 * none-zero).
 */
static int _sp2d_alloc(unsigned pages_in_unit, unsigned group_width,
		       unsigned parity, struct __stripe_pages_2d **psp2d)
{
	struct __stripe_pages_2d *sp2d;
	unsigned data_devs = group_width - parity;
	struct _alloc_all_bytes {
		struct __alloc_stripe_pages_2d {
			struct __stripe_pages_2d sp2d;
			struct __1_page_stripe _1p_stripes[pages_in_unit];
		} __asp2d;
		struct __alloc_1p_arrays {
			struct page *pages[group_width];
			struct page *scribble[group_width];
			char page_is_read[data_devs];
		} __a1pa[pages_in_unit];
	} *_aab;
	struct __alloc_1p_arrays *__a1pa;
	struct __alloc_1p_arrays *__a1pa_end;
	const unsigned sizeof__a1pa = sizeof(_aab->__a1pa[0]);
	unsigned num_a1pa, alloc_size, i;

	/* FIXME: check these numbers in ore_verify_layout */
	BUG_ON(sizeof(_aab->__asp2d) > PAGE_SIZE);
	BUG_ON(sizeof__a1pa > PAGE_SIZE);

	if (sizeof(*_aab) > PAGE_SIZE) {
		num_a1pa = (PAGE_SIZE - sizeof(_aab->__asp2d)) / sizeof__a1pa;
		alloc_size = sizeof(_aab->__asp2d) + sizeof__a1pa * num_a1pa;
	} else {
		num_a1pa = pages_in_unit;
		alloc_size = sizeof(*_aab);
	}

	_aab = kzalloc(alloc_size, GFP_KERNEL);
	if (unlikely(!_aab)) {
		ORE_DBGMSG("!! Failed to alloc sp2d size=%d\n", alloc_size);
		return -ENOMEM;
	}

	sp2d = &_aab->__asp2d.sp2d;
	*psp2d = sp2d; /* From here Just call _sp2d_free */

	__a1pa = _aab->__a1pa;
	__a1pa_end = __a1pa + num_a1pa;

	for (i = 0; i < pages_in_unit; ++i) {
		if (unlikely(__a1pa >= __a1pa_end)) {
			num_a1pa = min_t(unsigned, PAGE_SIZE / sizeof__a1pa,
							pages_in_unit - i);

			__a1pa = kzalloc(num_a1pa * sizeof__a1pa, GFP_KERNEL);
			if (unlikely(!__a1pa)) {
				ORE_DBGMSG("!! Failed to _alloc_1p_arrays=%d\n",
					   num_a1pa);
				return -ENOMEM;
			}
			__a1pa_end = __a1pa + num_a1pa;
			/* First *pages is marked for kfree of the buffer */
			sp2d->_1p_stripes[i].alloc = true;
		}

		sp2d->_1p_stripes[i].pages = __a1pa->pages;
		sp2d->_1p_stripes[i].scribble = __a1pa->scribble ;
		sp2d->_1p_stripes[i].page_is_read = __a1pa->page_is_read;
		++__a1pa;
	}

	sp2d->parity = parity;
	sp2d->data_devs = data_devs;
	sp2d->pages_in_unit = pages_in_unit;
	return 0;
}

static void _sp2d_reset(struct __stripe_pages_2d *sp2d,
			const struct _ore_r4w_op *r4w, void *priv)
{
	unsigned data_devs = sp2d->data_devs;
	unsigned group_width = data_devs + sp2d->parity;
	int p, c;

	if (!sp2d->needed)
		return;

	for (c = data_devs - 1; c >= 0; --c)
		for (p = sp2d->pages_in_unit - 1; p >= 0; --p) {
			struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p];

			if (_1ps->page_is_read[c]) {
				struct page *page = _1ps->pages[c];

				r4w->put_page(priv, page);
				_1ps->page_is_read[c] = false;
			}
		}

	for (p = 0; p < sp2d->pages_in_unit; p++) {
		struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p];

		memset(_1ps->pages, 0, group_width * sizeof(*_1ps->pages));
		_1ps->write_count = 0;
		_1ps->tx = NULL;
	}

	sp2d->needed = false;
}

static void _sp2d_free(struct __stripe_pages_2d *sp2d)
{
	unsigned i;

	if (!sp2d)
		return;

	for (i = 0; i < sp2d->pages_in_unit; ++i) {
		if (sp2d->_1p_stripes[i].alloc)
			kfree(sp2d->_1p_stripes[i].pages);
	}

	kfree(sp2d);
}

static unsigned _sp2d_min_pg(struct __stripe_pages_2d *sp2d)
{
	unsigned p;

	for (p = 0; p < sp2d->pages_in_unit; p++) {
		struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p];

		if (_1ps->write_count)
			return p;
	}

	return ~0;
}

static unsigned _sp2d_max_pg(struct __stripe_pages_2d *sp2d)
{
	int p;

	for (p = sp2d->pages_in_unit - 1; p >= 0; --p) {
		struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p];

		if (_1ps->write_count)
			return p;
	}

	return ~0;
}

static void _gen_xor_unit(struct __stripe_pages_2d *sp2d)
{
	unsigned p;
	for (p = 0; p < sp2d->pages_in_unit; p++) {
		struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p];

		if (!_1ps->write_count)
			continue;

		init_async_submit(&_1ps->submit,
			ASYNC_TX_XOR_ZERO_DST | ASYNC_TX_ACK,
			NULL,
			NULL, NULL,
			(addr_conv_t *)_1ps->scribble);

		/* TODO: raid6 */
		_1ps->tx = async_xor(_1ps->pages[sp2d->data_devs], _1ps->pages,
				     0, sp2d->data_devs, PAGE_SIZE,
				     &_1ps->submit);
	}

	for (p = 0; p < sp2d->pages_in_unit; p++) {
		struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p];
		/* NOTE: We wait for HW synchronously (I don't have such HW
		 * to test with.) Is parallelism needed with today's multi
		 * cores?
		 */
		async_tx_issue_pending(_1ps->tx);
	}
}

void _ore_add_stripe_page(struct __stripe_pages_2d *sp2d,
		       struct ore_striping_info *si, struct page *page)
{
	struct __1_page_stripe *_1ps;

	sp2d->needed = true;

	_1ps = &sp2d->_1p_stripes[si->cur_pg];
	_1ps->pages[si->cur_comp] = page;
	++_1ps->write_count;

	si->cur_pg = (si->cur_pg + 1) % sp2d->pages_in_unit;
	/* si->cur_comp is advanced outside at main loop */
}

void _ore_add_sg_seg(struct ore_per_dev_state *per_dev, unsigned cur_len,
		     bool not_last)
{
	struct osd_sg_entry *sge;

	ORE_DBGMSG("dev=%d cur_len=0x%x not_last=%d cur_sg=%d "
		     "offset=0x%llx length=0x%x last_sgs_total=0x%x\n",
		     per_dev->dev, cur_len, not_last, per_dev->cur_sg,
		     _LLU(per_dev->offset), per_dev->length,
		     per_dev->last_sgs_total);

	if (!per_dev->cur_sg) {
		sge = per_dev->sglist;

		/* First time we prepare two entries */
		if (per_dev->length) {
			++per_dev->cur_sg;
			sge->offset = per_dev->offset;
			sge->len = per_dev->length;
		} else {
			/* Here the parity is the first unit of this object.
			 * This happens every time we reach a parity device on
			 * the same stripe as the per_dev->offset. We need to
			 * just skip this unit.
			 */
			per_dev->offset += cur_len;
			return;
		}
	} else {
		/* finalize the last one */
		sge = &per_dev->sglist[per_dev->cur_sg - 1];
		sge->len = per_dev->length - per_dev->last_sgs_total;
	}

	if (not_last) {
		/* Partly prepare the next one */
		struct osd_sg_entry *next_sge = sge + 1;

		++per_dev->cur_sg;
		next_sge->offset = sge->offset + sge->len + cur_len;
		/* Save cur len so we know how mutch was added next time */
		per_dev->last_sgs_total = per_dev->length;
		next_sge->len = 0;
	} else if (!sge->len) {
		/* Optimize for when the last unit is a parity */
		--per_dev->cur_sg;
	}
}

static int _alloc_read_4_write(struct ore_io_state *ios)
{
	struct ore_layout *layout = ios->layout;
	int ret;
	/* We want to only read those pages not in cache so worst case
	 * is a stripe populated with every other page
	 */
	unsigned sgs_per_dev = ios->sp2d->pages_in_unit + 2;

	ret = _ore_get_io_state(layout, ios->oc,
				layout->group_width * layout->mirrors_p1,
				sgs_per_dev, 0, &ios->ios_read_4_write);
	return ret;
}

/* @si contains info of the to-be-inserted page. Update of @si should be
 * maintained by caller. Specificaly si->dev, si->obj_offset, ...
 */
static int _add_to_r4w(struct ore_io_state *ios, struct ore_striping_info *si,
		       struct page *page, unsigned pg_len)
{
	struct request_queue *q;
	struct ore_per_dev_state *per_dev;
	struct ore_io_state *read_ios;
	unsigned first_dev = si->dev - (si->dev %
			  (ios->layout->group_width * ios->layout->mirrors_p1));
	unsigned comp = si->dev - first_dev;
	unsigned added_len;

	if (!ios->ios_read_4_write) {
		int ret = _alloc_read_4_write(ios);

		if (unlikely(ret))
			return ret;
	}

	read_ios = ios->ios_read_4_write;
	read_ios->numdevs = ios->layout->group_width * ios->layout->mirrors_p1;

	per_dev = &read_ios->per_dev[comp];
	if (!per_dev->length) {
		per_dev->bio = bio_kmalloc(GFP_KERNEL,
					   ios->sp2d->pages_in_unit);
		if (unlikely(!per_dev->bio)) {
			ORE_DBGMSG("Failed to allocate BIO size=%u\n",
				     ios->sp2d->pages_in_unit);
			return -ENOMEM;
		}
		per_dev->offset = si->obj_offset;
		per_dev->dev = si->dev;
	} else if (si->obj_offset != (per_dev->offset + per_dev->length)) {
		u64 gap = si->obj_offset - (per_dev->offset + per_dev->length);

		_ore_add_sg_seg(per_dev, gap, true);
	}
	q = osd_request_queue(ore_comp_dev(read_ios->oc, per_dev->dev));
	added_len = bio_add_pc_page(q, per_dev->bio, page, pg_len,
				    si->obj_offset % PAGE_SIZE);
	if (unlikely(added_len != pg_len)) {
		ORE_DBGMSG("Failed to bio_add_pc_page bi_vcnt=%d\n",
			      per_dev->bio->bi_vcnt);
		return -ENOMEM;
	}

	per_dev->length += pg_len;
	return 0;
}

/* read the beginning of an unaligned first page */
static int _add_to_r4w_first_page(struct ore_io_state *ios, struct page *page)
{
	struct ore_striping_info si;
	unsigned pg_len;

	ore_calc_stripe_info(ios->layout, ios->offset, 0, &si);

	pg_len = si.obj_offset % PAGE_SIZE;
	si.obj_offset -= pg_len;

	ORE_DBGMSG("offset=0x%llx len=0x%x index=0x%lx dev=%x\n",
		   _LLU(si.obj_offset), pg_len, page->index, si.dev);

	return _add_to_r4w(ios, &si, page, pg_len);
}

/* read the end of an incomplete last page */
static int _add_to_r4w_last_page(struct ore_io_state *ios, u64 *offset)
{
	struct ore_striping_info si;
	struct page *page;
	unsigned pg_len, p, c;

	ore_calc_stripe_info(ios->layout, *offset, 0, &si);

	p = si.unit_off / PAGE_SIZE;
	c = _dev_order(ios->layout->group_width * ios->layout->mirrors_p1,
		       ios->layout->mirrors_p1, si.par_dev, si.dev);
	page = ios->sp2d->_1p_stripes[p].pages[c];

	pg_len = PAGE_SIZE - (si.unit_off % PAGE_SIZE);
	*offset += pg_len;

	ORE_DBGMSG("p=%d, c=%d next-offset=0x%llx len=0x%x dev=%x par_dev=%d\n",
		   p, c, _LLU(*offset), pg_len, si.dev, si.par_dev);

	BUG_ON(!page);

	return _add_to_r4w(ios, &si, page, pg_len);
}

static void _mark_read4write_pages_uptodate(struct ore_io_state *ios, int ret)
{
	struct bio_vec *bv;
	unsigned i, d;

	/* loop on all devices all pages */
	for (d = 0; d < ios->numdevs; d++) {
		struct bio *bio = ios->per_dev[d].bio;

		if (!bio)
			continue;

		__bio_for_each_segment(bv, bio, i, 0) {
			struct page *page = bv->bv_page;

			SetPageUptodate(page);
			if (PageError(page))
				ClearPageError(page);
		}
	}
}

/* read_4_write is hacked to read the start of the first stripe and/or
 * the end of the last stripe. If needed, with an sg-gap at each device/page.
 * It is assumed to be called after the to_be_written pages of the first stripe
 * are populating ios->sp2d[][]
 *
 * NOTE: We call ios->r4w->lock_fn for all pages needed for parity calculations
 * These pages are held at sp2d[p].pages[c] but with
 * sp2d[p].page_is_read[c] = true. At _sp2d_reset these pages are
 * ios->r4w->lock_fn(). The ios->r4w->lock_fn might signal that the page is
 * @uptodate=true, so we don't need to read it, only unlock, after IO.
 *
 * TODO: The read_4_write should calc a need_to_read_pages_count, if bigger then
 * to-be-written count, we should consider the xor-in-place mode.
 * need_to_read_pages_count is the actual number of pages not present in cache.
 * maybe "devs_in_group - ios->sp2d[p].write_count" is a good enough
 * approximation? In this mode the read pages are put in the empty places of
 * ios->sp2d[p][*], xor is calculated the same way. These pages are
 * allocated/freed and don't go through cache
 */
static int _read_4_write_first_stripe(struct ore_io_state *ios)
{
	struct ore_striping_info read_si;
	struct __stripe_pages_2d *sp2d = ios->sp2d;
	u64 offset = ios->si.first_stripe_start;
	unsigned c, p, min_p = sp2d->pages_in_unit, max_p = -1;

	if (offset == ios->offset) /* Go to start collect $200 */
		goto read_last_stripe;

	min_p = _sp2d_min_pg(sp2d);
	max_p = _sp2d_max_pg(sp2d);

	ORE_DBGMSG("stripe_start=0x%llx ios->offset=0x%llx min_p=%d max_p=%d\n",
		   offset, ios->offset, min_p, max_p);

	for (c = 0; ; c++) {
		ore_calc_stripe_info(ios->layout, offset, 0, &read_si);
		read_si.obj_offset += min_p * PAGE_SIZE;
		offset += min_p * PAGE_SIZE;
		for (p = min_p; p <= max_p; p++) {
			struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p];
			struct page **pp = &_1ps->pages[c];
			bool uptodate;

			if (*pp) {
				if (ios->offset % PAGE_SIZE)
					/* Read the remainder of the page */
					_add_to_r4w_first_page(ios, *pp);
				/* to-be-written pages start here */
				goto read_last_stripe;
			}

			*pp = ios->r4w->get_page(ios->private, offset,
						 &uptodate);
			if (unlikely(!*pp))
				return -ENOMEM;

			if (!uptodate)
				_add_to_r4w(ios, &read_si, *pp, PAGE_SIZE);

			/* Mark read-pages to be cache_released */
			_1ps->page_is_read[c] = true;
			read_si.obj_offset += PAGE_SIZE;
			offset += PAGE_SIZE;
		}
		offset += (sp2d->pages_in_unit - p) * PAGE_SIZE;
	}

read_last_stripe:
	return 0;
}

static int _read_4_write_last_stripe(struct ore_io_state *ios)
{
	struct ore_striping_info read_si;
	struct __stripe_pages_2d *sp2d = ios->sp2d;
	u64 offset;
	u64 last_stripe_end;
	unsigned bytes_in_stripe = ios->si.bytes_in_stripe;
	unsigned c, p, min_p = sp2d->pages_in_unit, max_p = -1;

	offset = ios->offset + ios->length;
	if (offset % PAGE_SIZE)
		_add_to_r4w_last_page(ios, &offset);
		/* offset will be aligned to next page */

	last_stripe_end = div_u64(offset + bytes_in_stripe - 1, bytes_in_stripe)
				 * bytes_in_stripe;
	if (offset == last_stripe_end) /* Optimize for the aligned case */
		goto read_it;

	ore_calc_stripe_info(ios->layout, offset, 0, &read_si);
	p = read_si.unit_off / PAGE_SIZE;
	c = _dev_order(ios->layout->group_width * ios->layout->mirrors_p1,
		       ios->layout->mirrors_p1, read_si.par_dev, read_si.dev);

	if (min_p == sp2d->pages_in_unit) {
		/* Didn't do it yet */
		min_p = _sp2d_min_pg(sp2d);
		max_p = _sp2d_max_pg(sp2d);
	}

	ORE_DBGMSG("offset=0x%llx stripe_end=0x%llx min_p=%d max_p=%d\n",
		   offset, last_stripe_end, min_p, max_p);

	while (offset < last_stripe_end) {
		struct __1_page_stripe *_1ps = &sp2d->_1p_stripes[p];

		if ((min_p <= p) && (p <= max_p)) {
			struct page *page;
			bool uptodate;

			BUG_ON(_1ps->pages[c]);
			page = ios->r4w->get_page(ios->private, offset,
						  &uptodate);
			if (unlikely(!page))
				return -ENOMEM;

			_1ps->pages[c] = page;
			/* Mark read-pages to be cache_released */
			_1ps->page_is_read[c] = true;
			if (!uptodate)
				_add_to_r4w(ios, &read_si, page, PAGE_SIZE);
		}

		offset += PAGE_SIZE;
		if (p == (sp2d->pages_in_unit - 1)) {
			++c;
			p = 0;
			ore_calc_stripe_info(ios->layout, offset, 0, &read_si);
		} else {
			read_si.obj_offset += PAGE_SIZE;
			++p;
		}
	}

read_it:
	return 0;
}

static int _read_4_write_execute(struct ore_io_state *ios)
{
	struct ore_io_state *ios_read;
	unsigned i;
	int ret;

	ios_read = ios->ios_read_4_write;
	if (!ios_read)
		return 0;

	/* FIXME: Ugly to signal _sbi_read_mirror that we have bio(s). Change
	 * to check for per_dev->bio
	 */
	ios_read->pages = ios->pages;

	/* Now read these devices */
	for (i = 0; i < ios_read->numdevs; i += ios_read->layout->mirrors_p1) {
		ret = _ore_read_mirror(ios_read, i);
		if (unlikely(ret))
			return ret;
	}

	ret = ore_io_execute(ios_read); /* Synchronus execution */
	if (unlikely(ret)) {
		ORE_DBGMSG("!! ore_io_execute => %d\n", ret);
		return ret;
	}

	_mark_read4write_pages_uptodate(ios_read, ret);
	ore_put_io_state(ios_read);
	ios->ios_read_4_write = NULL; /* Might need a reuse at last stripe */
	return 0;
}

/* In writes @cur_len means length left. .i.e cur_len==0 is the last parity U */
int _ore_add_parity_unit(struct ore_io_state *ios,
			    struct ore_striping_info *si,
			    struct ore_per_dev_state *per_dev,
			    unsigned cur_len)
{
	if (ios->reading) {
		if (per_dev->cur_sg >= ios->sgs_per_dev) {
			ORE_DBGMSG("cur_sg(%d) >= sgs_per_dev(%d)\n" ,
				per_dev->cur_sg, ios->sgs_per_dev);
			return -ENOMEM;
		}
		_ore_add_sg_seg(per_dev, cur_len, true);
	} else {
		struct __stripe_pages_2d *sp2d = ios->sp2d;
		struct page **pages = ios->parity_pages + ios->cur_par_page;
		unsigned num_pages;
		unsigned array_start = 0;
		unsigned i;
		int ret;

		si->cur_pg = _sp2d_min_pg(sp2d);
		num_pages  = _sp2d_max_pg(sp2d) + 1 - si->cur_pg;

		if (!cur_len) /* If last stripe operate on parity comp */
			si->cur_comp = sp2d->data_devs;

		if (!per_dev->length) {
			per_dev->offset += si->cur_pg * PAGE_SIZE;
			/* If first stripe, Read in all read4write pages
			 * (if needed) before we calculate the first parity.
			 */
			_read_4_write_first_stripe(ios);
		}
		if (!cur_len) /* If last stripe r4w pages of last stripe */
			_read_4_write_last_stripe(ios);
		_read_4_write_execute(ios);

		for (i = 0; i < num_pages; i++) {
			pages[i] = _raid_page_alloc();
			if (unlikely(!pages[i]))
				return -ENOMEM;

			++(ios->cur_par_page);
		}

		BUG_ON(si->cur_comp != sp2d->data_devs);
		BUG_ON(si->cur_pg + num_pages > sp2d->pages_in_unit);

		ret = _ore_add_stripe_unit(ios,  &array_start, 0, pages,
					   per_dev, num_pages * PAGE_SIZE);
		if (unlikely(ret))
			return ret;

		/* TODO: raid6 if (last_parity_dev) */
		_gen_xor_unit(sp2d);
		_sp2d_reset(sp2d, ios->r4w, ios->private);
	}
	return 0;
}

int _ore_post_alloc_raid_stuff(struct ore_io_state *ios)
{
	if (ios->parity_pages) {
		struct ore_layout *layout = ios->layout;
		unsigned pages_in_unit = layout->stripe_unit / PAGE_SIZE;

		if (_sp2d_alloc(pages_in_unit, layout->group_width,
				layout->parity, &ios->sp2d)) {
			return -ENOMEM;
		}
	}
	return 0;
}

void _ore_free_raid_stuff(struct ore_io_state *ios)
{
	if (ios->sp2d) { /* writing and raid */
		unsigned i;

		for (i = 0; i < ios->cur_par_page; i++) {
			struct page *page = ios->parity_pages[i];

			if (page)
				_raid_page_free(page);
		}
		if (ios->extra_part_alloc)
			kfree(ios->parity_pages);
		/* If IO returned an error pages might need unlocking */
		_sp2d_reset(ios->sp2d, ios->r4w, ios->private);
		_sp2d_free(ios->sp2d);
	} else {
		/* Will only be set if raid reading && sglist is big */
		if (ios->extra_part_alloc)
			kfree(ios->per_dev[0].sglist);
	}
	if (ios->ios_read_4_write)
		ore_put_io_state(ios->ios_read_4_write);
}
