fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or http://www.opensolaris.org/os/licensing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/types.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/param.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ksynch.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/kmem.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/stat.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/buf.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/open.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/conf.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/file.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/cmn_err.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/errno.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ddi.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/nsc_thread.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/nsctl/nsctl.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/sdt.h> /* dtrace is S10 or later */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
af4c679f647cf088543c762e33d41a3ac52cfa14Sean McEnroe#include <vm/seg_kmem.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sd_bcache.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sd_trace.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sd_io.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sd_iob.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sd_misc.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#if defined(_SD_DEBUG) /* simulate disk errors */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include "sd_tdaemon.h"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifndef DS_DDICT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteextern uintptr_t kobj_getsymvalue(char *, int); /* DDI violation */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define DO_PAGE_LIST sdbc_do_page /* enable pagelist code */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint sdbc_do_page = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define SGIO_MAX 254
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic kmutex_t sdbc_bio_mutex;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sdbc_bio_count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic unsigned long page_size, page_offset_mask;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _SD_BIO_STATS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic __start_io_count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _SD_BIO_STATS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Forward declare all statics that are used before defined to enforce
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * parameter checking. Also forward-declare all functions that have 64-bit
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * argument types to enforce correct parameter checking.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Some (if not all) of these could be removed if the code were reordered
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _sd_sync_ea(struct buf *, iob_hook_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _sd_async_ea(struct buf *, iob_hook_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void _sd_pack_pages(struct buf *bp, struct buf *list, sd_addr_t *addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t offset, nsc_size_t size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void _sd_pack_pages_nopageio(struct buf *bp, struct buf *list,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sd_addr_t *addr, nsc_off_t offset, nsc_size_t size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void _sd_setup_iob(struct buf *bp, dev_t dev, nsc_off_t pos, int flag);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int _sdbc_ioj_lookup(dev_t);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void _sdbc_ioj_clear_err(int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int SD_WRITES_TOT = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int SD_WRITES_LEN[100];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_buf_list_t _sd_buflist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sd_add_vm_to_bp_plist - add the page corresponding to the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * virtual address "v" (kernel virtaddr) to the pagelist linked
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to buffer "bp".
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The virtual address "v" is "known" to be allocated by segkmem
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and we can look up the page by using the segkmem vnode kvp.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This violates the ddi/ddk but is workable for now anyway.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_add_vm_to_bp_plist(struct buf *bp, unsigned char *v)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte page_t *pp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte page_t *one_pg = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pp = page_find(&kvp, (u_offset_t)((uintptr_t)v & ~page_offset_mask));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!pp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_PANIC,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "_sd_add_vm_to_bp_plist: couldn't find page for 0x%p",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)v);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte page_add(&one_pg, pp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte page_list_concat(&(bp->b_pages), &one_pg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _SD_BIO_STATS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_count_pages(page_t *pp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cnt = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte page_t *pp1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pp == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (cnt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cnt = 1, pp1 = pp->p_next; pp != pp1; cnt++, pp1 = pp1->p_next)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (cnt);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _SD_BIO_STATS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sdbc_iobuf_load - load time initialization of io bufs structures.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * RETURNS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 0 - success.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * -1 - failure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * USAGE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This routine initializes load time buf structures.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Should be called when the cache is loaded.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_iobuf_load(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&sdbc_bio_mutex, NULL, MUTEX_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * HACK add a ref to kvp, to prevent VN_RELE on it from panicing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the system
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte VN_HOLD(&kvp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sdbc_iobuf_unload - unload time cleanup of io buf structures.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * USAGE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This routine removes load time buf structures.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Should be called when the cache is unloaded.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_iobuf_unload(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Undo our VN_HOLD hack, by putting ref count back to normal state */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&kvp.v_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kvp.v_count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&kvp.v_lock);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&sdbc_bio_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(&_sd_buflist, sizeof (_sd_buf_list_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sdbc_iobuf_configure - configure a list of io bufs for later use.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ARGUMENTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * num_bufs - number of buffers. (from the configuration file)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * RETURNS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 0 - success.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * <0 - failure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * USAGE:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This routine configures the buf structures for io.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Should be called when the cache is configured.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_iobuf_configure(int num)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_buf_list_t *buflist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iob_hook_t *hook;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char symbol_name[32];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!num || (num > _SD_DEFAULT_IOBUFS))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num = _SD_DEFAULT_IOBUFS;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((_sd_buflist.hooks = (iob_hook_t *)nsc_kmem_zalloc(
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana num * sizeof (iob_hook_t), KM_SLEEP, sdbc_iobuf_mem)) == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buflist = &_sd_buflist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buflist->bl_init_count = num;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buflist->bl_hooks_avail = num;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buflist->bl_hook_lowmark = num;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook = buflist->hooks;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buflist->hook_head = hook;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < num; i++, hook++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&hook->wait, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sprintf(symbol_name, "sd_iob_dcb%d", i);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->iob_drv_iodone = (dcb_t)kobj_getsymvalue(symbol_name, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!hook->iob_drv_iodone) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-2);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->next_hook = hook+1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (hook-1)->next_hook = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < MAX_HOOK_LOCKS; i++)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_init(&_sd_buflist.hook_locks[i], NULL, MUTEX_DRIVER,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_init(&_sd_buflist.hook_wait, NULL, CV_DRIVER, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_buflist.hook_waiters = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sdbc_bio_count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte SD_WRITES_TOT = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bzero(SD_WRITES_LEN, sizeof (SD_WRITES_LEN));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* pagelist i/o pages must be done in cache_init */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte page_size = ptob(1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte page_offset_mask = page_size - 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sdbc_iobuf_deconfigure - release all memory allocated for buf list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ARGUMENTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * None.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * RETURNS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_iobuf_deconfigure(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ushort_t i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_sd_buflist.hooks) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < _sd_buflist.bl_init_count; i ++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&_sd_buflist.hooks[i].wait);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_destroy(&_sd_buflist.hook_wait);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_kmem_free(_sd_buflist.hooks,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana _sd_buflist.bl_init_count * sizeof (iob_hook_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < MAX_HOOK_LOCKS; i ++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_destroy(&_sd_buflist.hook_locks[i]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_buflist.hooks = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte void _sdbc_ioj_clear_err(int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdbc_ioj_clear_err(-1); /* clear any injected i/o errors */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdbc_ioj_set_dev(-1, 0); /* clear dev entries */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sd_pending_iobuf()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Return the number of I/O bufs outstanding
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_pending_iobuf(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (sdbc_bio_count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sd_get_iobuf - allocate a buf.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ARGUMENTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * None.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * RETURNS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NULL - failure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * buf ptr otherwise.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ASSUMPTIONS - process could block if we run out.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*ARGSUSED*/
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct buf *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_get_iobuf(int num_bdl)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct buf *bp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Get a buffer, ready for page list i/o */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (DO_PAGE_LIST)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp = pageio_setup(NULL, 0, &kvp, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp = getrbuf(KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bp == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sdbc_bio_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sdbc_bio_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sdbc_bio_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sd_put_iobuf - put a buf back in the freelist.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ARGUMENTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bp - buf pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * RETURNS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_put_iobuf(struct buf *bp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sdbc_bio_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sdbc_bio_count--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sdbc_bio_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (DO_PAGE_LIST)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pageio_done(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte freerbuf(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* use for ORing only */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define B_KERNBUF 0
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_setup_iob(struct buf *bp, dev_t dev, nsc_off_t pos, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_pages = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_un.b_addr = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flag &= (B_READ | B_WRITE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * if pagelist i/o, _sd_get_iobuf()/pageio_setup() has already
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set b_flags to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * B_KERNBUF | B_PAGEIO | B_NOCACHE | B_BUSY (sol 6,7,8)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * B_PAGEIO | B_NOCACHE | B_BUSY (sol 9)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_flags |= B_KERNBUF | B_BUSY | flag;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_error = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_forw = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_back = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_lblkno = (diskaddr_t)pos;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_bufsize = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_resid = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_proc = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_edev = dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sd_get_hook - get an iob hook from the free list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ARGUMENTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * none
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * RETURNS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the newly allocated iob_hook.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic iob_hook_t *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_get_hook(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iob_hook_t *ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sdbc_bio_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteretry:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = _sd_buflist.hook_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_buflist.hook_head = ret->next_hook;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ++_sd_buflist.hook_waiters;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_sd_buflist.max_hook_waiters < _sd_buflist.hook_waiters)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_buflist.max_hook_waiters = _sd_buflist.hook_waiters;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_wait(&_sd_buflist.hook_wait, &sdbc_bio_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte --_sd_buflist.hook_waiters;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto retry;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_sd_buflist.bl_hook_lowmark > --_sd_buflist.bl_hooks_avail)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_buflist.bl_hook_lowmark = _sd_buflist.bl_hooks_avail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sdbc_bio_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret->skipped = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret->count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _SD_BIO_STATS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret->PAGE_IO = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret->NORM_IO = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret->NORM_IO_SIZE = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret->SKIP_IO = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret->PAGE_COMBINED = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _SD_BIO_STATS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sd_put_hook - put an iob hook back on the free list.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ARGUMENTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * hook - an iob_hook to be returned to the freelist.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_put_hook(iob_hook_t *hook)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(&sdbc_bio_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_sd_buflist.hook_waiters) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&_sd_buflist.hook_wait);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->next_hook = _sd_buflist.hook_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_buflist.hook_head = hook;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ++_sd_buflist.bl_hooks_avail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(&sdbc_bio_mutex);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sd_extend_iob - the i/o block we are handling needs a new struct buf to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * describe the next hunk of i/o. Get a new struct buf initialize it based
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * on the state in the struct buf we are passed as an arg.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ARGUMENTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * head_bp - a buffer header in the current i/o block we are handling.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (generally the initial header but in fact could be any
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * of the ones [if any] that were chained to the initial
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * one).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct buf *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_extend_iob(struct buf *head_bp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct buf *bp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iob_hook_t *hook = (iob_hook_t *)head_bp->b_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(bp = _sd_get_iobuf(0)))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_pages = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_un.b_addr = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_flags |= (head_bp->b_flags & (B_READ | B_WRITE));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!DO_PAGE_LIST)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_flags |= B_KERNBUF | B_BUSY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_error = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * b_forw/b_back will form a doubly linked list of all the buffers
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * associated with this block of i/o.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * hook->tail points to the last buffer in the chain.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_forw = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_back = hook->tail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->tail->b_forw = bp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->tail = bp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(BLK_FBA_OFF(hook->size) == 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_lblkno = (diskaddr_t)hook->start_fba +
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana (diskaddr_t)FBA_NUM(hook->size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_bufsize = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_resid = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_proc = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_edev = head_bp->b_edev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_iodone = NULL; /* for now */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_private = hook;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sd_alloc_iob - start processing a block of i/o. This allocates an initial
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * buffer header for describing the i/o and a iob_hook for collecting
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information about all the i/o requests added to this buffer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ARGUMENTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dev - the device all the i/o is destined for.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fba_pos - the initial disk block to read.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * blks - ignored
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * flag - signal whether this is a read or write request.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * RETURNS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pointer to free struct buf which will be used to describe i/o request.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestruct buf *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesd_alloc_iob(dev_t dev, nsc_off_t fba_pos, int blks, int flag)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct buf *bp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iob_hook_t *hook;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(bp = _sd_get_iobuf(0)))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_setup_iob(bp, dev, fba_pos, flag);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_iodone = NULL; /* for now */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook = _sd_get_hook();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!hook) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* can't see how this could happen */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_put_iobuf(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pick an arbitrary lock
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->lockp = &_sd_buflist.hook_locks[((long)hook >> 9) &
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana (MAX_HOOK_LOCKS - 1)];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->start_fba = fba_pos;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->last_fba = fba_pos;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->size = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->tail = bp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->chain = bp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->count = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->error = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_private = hook;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sd_pack_pages - produce i/o requests that will perform the type of i/o
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * described by bp (READ/WRITE). It attempt to tack the i/o onto the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * buf pointer to by list to minimize the number of bufs required.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ARGUMENTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bp - is the i/o description i.e. head
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * list - is where to start adding this i/o request (null if we should extend)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * addr - address describing where the data is.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * offset - offset from addr where data begins
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * size - size of the i/o request.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_pack_pages(struct buf *bp, struct buf *list, sd_addr_t *addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t offset, nsc_size_t size)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uintptr_t start_addr, end_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int page_end_aligned;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _SD_BIO_STATS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iob_hook_t *hook = (iob_hook_t *)bp->b_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct buf *orig_list = list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _SD_BIO_STATS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte start_addr = (uintptr_t)addr->sa_virt + offset;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte end_addr = start_addr + size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte page_end_aligned = !(end_addr & page_offset_mask);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!list && !(list = _sd_extend_iob(bp))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we're hosed since we have no error return...
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * though we could ignore stuff from here on out
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and return ENOMEM when we get to sd_start_io.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This will do for now.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_PANIC, "_sd_pack_pages: couldn't extend iob");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We only want to do pagelist i/o if we end on a page boundary.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we don't end on a page boundary we won't combine with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * next request and so we may as well do it as normal as it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * will only use one buffer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (DO_PAGE_LIST && page_end_aligned) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (start_addr & page_offset_mask) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * handle the partial page
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (list->b_bufsize) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(list = _sd_extend_iob(bp))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we're hosed since we have no error
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return though we could ignore stuff
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * from here on out and return ENOMEM
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * when we get to sd_start_io.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This will do for now.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_PANIC,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "_sd_pack_pages: couldn't extend iob");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _SD_BIO_STATS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->PAGE_IO++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _SD_BIO_STATS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_add_vm_to_bp_plist(list,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana (unsigned char *) start_addr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->b_bufsize = page_size -
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana (start_addr & page_offset_mask);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->b_un.b_addr = (caddr_t)
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana (start_addr & page_offset_mask);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size -= list->b_bufsize;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte start_addr += list->b_bufsize;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Now fill with all the full pages remaining.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (; size > 0; size -= page_size) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _SD_BIO_STATS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->PAGE_IO++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _SD_BIO_STATS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_add_vm_to_bp_plist(list,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana (unsigned char *) start_addr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte start_addr += page_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->b_bufsize += page_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _SD_BIO_STATS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (list == orig_list)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->PAGE_COMBINED++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _SD_BIO_STATS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (size)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_PANIC, "_sd_pack_pages: bad size: %"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NSC_SZFMT, size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Wasn't worth it as pagelist i/o, do as normal
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (list->b_bufsize && !(list = _sd_extend_iob(bp))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we're hosed since we have no error return...
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * though we could ignore stuff from here on out
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and return ENOMEM when we get to sd_start_io.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This will do for now.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_PANIC,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "_sd_pack_pages: couldn't extend iob");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* kernel virtual */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->b_flags &= ~(B_PHYS | B_PAGEIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->b_un.b_addr = (caddr_t)start_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _SD_BIO_STATS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->NORM_IO++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->NORM_IO_SIZE += size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _SD_BIO_STATS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->b_bufsize = (size_t)size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * perform same function as _sd_pack_pages() when not doing pageio
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_pack_pages_nopageio(struct buf *bp, struct buf *list, sd_addr_t *addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t offset, nsc_size_t size)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uintptr_t start_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _SD_BIO_STATS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iob_hook_t *hook = (iob_hook_t *)bp->b_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct buf *orig_list = list;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _SD_BIO_STATS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte start_addr = (uintptr_t)addr->sa_virt + offset;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!list && !(list = _sd_extend_iob(bp))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we're hosed since we have no error return...
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * though we could ignore stuff from here on out
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and return ENOMEM when we get to sd_start_io.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This will do for now.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_PANIC, "_sd_pack_pages_nopageio: couldn't "
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "extend iob");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (list->b_bufsize &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (start_addr == (uintptr_t)(list->b_un.b_addr + list->b_bufsize))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* contiguous */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->b_bufsize += (size_t)size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * not contiguous mem (extend) or first buffer (bufsize == 0).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (list->b_bufsize && !(list = _sd_extend_iob(bp))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we're hosed since we have no error return...
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * though we could ignore stuff from here on out
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and return ENOMEM when we get to sd_start_io.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This will do for now.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_PANIC, "_sd_pack_pages_nopageio: couldn't "
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "extend iob");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->b_un.b_addr = (caddr_t)start_addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte list->b_bufsize = (size_t)size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _SD_BIO_STATS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->NORM_IO++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->NORM_IO_SIZE += size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _SD_BIO_STATS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sd_add_fba - add an i/o request to the block of i/o described by bp.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We try and combine this request with the previous request. In
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Addition we try and do the i/o as PAGELIST_IO if it satisfies
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the restrictions for it. If the i/o request can't be combined
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we extend the i/o description with a new buffer header and add
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * it to the chain headed by bp.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ARGUMENTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bp - the struct buf describing the block i/o we are collecting.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * addr - description of the address where the data will read/written to.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * A NULL indicates that this i/o request doesn't need to actually
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * happen. Used to mark reads when the fba is already in cache and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dirty.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fba_pos - offset from address in addr where the i/o is to start.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fba_len - number of consecutive fbas to transfer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NOTE: It is assumed that the memory is physically contiguous but may span
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * multiple pages (should a cache block be larger than a page).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesd_add_fba(struct buf *bp, sd_addr_t *addr, nsc_off_t fba_pos,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t fba_len)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t offset;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iob_hook_t *hook = (iob_hook_t *)bp->b_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte size = FBA_SIZE(fba_len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte offset = FBA_SIZE(fba_pos);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (addr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See if this can be combined with previous request(s)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!bp->b_bufsize) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (DO_PAGE_LIST)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_pack_pages(bp, bp, addr, offset, size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_pack_pages_nopageio(bp, bp, addr, offset,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (DO_PAGE_LIST) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (hook->tail->b_flags & B_PAGEIO) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Last buffer was a pagelist. Unless a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * skip was detected the last request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ended on a page boundary. If this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * one starts on one we combine the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * best we can.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (hook->skipped)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_pack_pages(bp, NULL, addr,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana offset, size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_pack_pages(bp, hook->tail,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana addr, offset, size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Last buffer was vanilla i/o or worse
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (sd_add_mem)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_pack_pages(bp, NULL, addr, offset,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (hook->skipped)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_pack_pages_nopageio(bp, NULL,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana addr, offset, size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_pack_pages_nopageio(bp,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana hook->tail, addr, offset, size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->skipped = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Must be a read of dirty block we want to discard */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ASSERT(bp->b_flags & B_READ);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _SD_BIO_STATS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->SKIP_IO++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _SD_BIO_STATS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->skipped = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!bp->b_bufsize)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_lblkno += fba_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->size += size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sd_add_mem - add an i/o request to the block of i/o described by bp.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The memory target for this i/o may span multiple pages and may
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * not be physically contiguous.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * also the len might also not be a multiple of an fba.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ARGUMENTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bp - the struct buf describing the block i/o we are collecting.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * buf - target of this i/o request.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * len - number of bytes to transfer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesd_add_mem(struct buf *bp, char *buf, nsc_size_t len)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t n;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uintptr_t start;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iob_hook_t *hook = (iob_hook_t *)bp->b_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte start = (uintptr_t)buf & page_offset_mask;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (; len > 0; buf += n, len -= n, start = 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte n = min((nsc_size_t)len, (nsc_size_t)(page_size - start));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * i/o size must be multiple of an FBA since we can't
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * count on lower level drivers to understand b_offset
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (BLK_FBA_OFF(n) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!sdbc(sd_add_mem) i/o request not FBA sized (%"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NSC_SZFMT ")", n);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!bp->b_bufsize) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* first request */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_flags &= ~(B_PHYS | B_PAGEIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_un.b_addr = buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_bufsize = (size_t)n;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct buf *new_bp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(new_bp = _sd_extend_iob(bp))) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* we're hosed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_PANIC,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "sd_add_mem: couldn't extend iob");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_bp->b_flags &= ~(B_PHYS | B_PAGEIO);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_bp->b_un.b_addr = buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_bp->b_bufsize = (size_t)n;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->size += n;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * sd_start_io - start all the i/o needed to satisfy the i/o request described
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by bp. If supplied the a non-NULL fn then this is an async request
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and we will return NSC_PENDING and call fn when all the i/o complete.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Otherwise this is a synchronous request and we sleep until all the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * i/o is complete. If any buffer in the chain gets an error we return
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the first error we see (once all the i/o is complete).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ARGUMENTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bp - the struct buf describing the block i/o we are collecting.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * strategy - strategy function to call if known by the user, or NULL.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fn - user's callback function. NULL implies synchronous request.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * arg - an argument passed to user's callback function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesd_start_io(struct buf *bp, strategy_fn_t strategy, sdbc_ea_fn_t fn,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte blind_t arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int err;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte iob_hook_t *hook = (iob_hook_t *)bp->b_private;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct buf *bp_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int (*ea_fn)(struct buf *, iob_hook_t *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _SD_BIO_STATS
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana static int total_pages, total_pages_combined, total_norm;
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana static int total_norm_combined, total_skipped;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte static nsc_size_t total_norm_size;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte static int total_bufs;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte static int total_xpages_w, total_ypages_w;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte static int total_xpages_r, total_ypages_r;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte static int max_run_r, max_run_w;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _SD_BIO_STATS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->func = fn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->param = arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fn != NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ea_fn = _sd_async_ea;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ea_fn = _sd_sync_ea;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->iob_hook_iodone = ea_fn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _SD_BIO_STATS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte __start_io_count++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_pages += hook->PAGE_IO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_pages_combined += hook->PAGE_COMBINED;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_norm += hook->NORM_IO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_norm_size += hook->NORM_IO_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_skipped += hook->SKIP_IO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _SD_BIO_STATS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (; bp; bp = bp_next) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana DTRACE_PROBE4(sd_start_io_bufs, struct buf *, bp, long, bp->b_bufsize,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana int, bp->b_flags, iob_hook_t *, hook);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp_next = bp->b_forw;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!(bp->b_flags & B_READ)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte SD_WRITES_TOT++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte SD_WRITES_LEN[(bp->b_bufsize/32768) %
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana (sizeof (SD_WRITES_LEN)/sizeof (int))]++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_iodone = hook->iob_drv_iodone;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_bcount = bp->b_bufsize;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_forw = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_back = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_private = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _SD_BIO_STATS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_bufs ++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bp->b_flags & B_PAGEIO) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i = _sd_count_pages(bp->b_pages);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bp->b_flags & B_READ) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (i > max_run_r)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte max_run_r = i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_xpages_r += i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_ypages_r++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (i > max_run_w)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte max_run_w = i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_xpages_w += i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_ypages_w++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _SD_BIO_STATS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It's possible for us to be told to read a dirty block
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * where all the i/o can go away (e.g. read one fba, it's
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in cache and dirty) so we really have nothing to do but
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * say we're done.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bp->b_bcount) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!strategy) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strategy =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_get_strategy(getmajor(bp->b_edev));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!strategy) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_flags |= B_ERROR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_error = ENXIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*bp->b_iodone)(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* inject i/o error for testing */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (bp->b_error = _sdbc_ioj_lookup(bp->b_edev)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_flags |= B_ERROR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*bp->b_iodone)(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*strategy)(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*bp->b_iodone)(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef _SD_BIO_STATS
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (__start_io_count == 2000) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte __start_io_count = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!sdbc(sd_start_io) t_bufs %d pages %d "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "combined %d norm %d norm_size %" NSC_SZFMT " skipped %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_bufs,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_pages, total_pages_combined, total_norm,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_norm_size, total_skipped);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_bufs = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_pages = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_pages_combined = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_norm = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_norm_combined = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_skipped = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_norm_size = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!sdbc(sd_start_io)(r) max_run %d, total_xp %d total yp %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte max_run_r, total_xpages_r, total_ypages_r);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_xpages_r = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_ypages_r = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte max_run_r = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cmn_err(CE_WARN,
3270659f55e0928d6edec3d26217cc29398a8149Srikanth, Ramana "!sdbc(sd_start_io)(w) max_run %d, total_xp %d total yp %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte max_run_w, total_xpages_w, total_ypages_w);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_xpages_w = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte total_ypages_w = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte max_run_w = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* _SD_BIO_STATS */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ea_fn == _sd_async_ea) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte DTRACE_PROBE(sd_start_io_end);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NSC_PENDING);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(hook->lockp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (hook->count) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_wait(&hook->wait, hook->lockp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(hook->lockp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte err = hook->error ? hook->error : NSC_DONE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp = hook->tail;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_put_hook(hook);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_put_iobuf(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (err);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sd_sync_ea - called when a single i/o operation is complete. If this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * is the last outstanding i/o we wakeup the sleeper.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If this i/o had an error then we store the error result in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * iob_hook if this was the first error.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ARGUMENTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bp - the struct buf describing the block i/o that just completed.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Comments:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This routine is called at interrupt level when the io is done.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_sync_ea(struct buf *bp, iob_hook_t *hook)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int done;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We get called for each buf that completes. When they are all done.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we wakeup the waiter.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte error = (bp->b_flags & B_ERROR) ? bp->b_error : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(hook->lockp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!hook->error)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->error = error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte done = !(--hook->count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (done) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* remember the last buffer so we can free it later */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->tail = bp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cv_signal(&hook->wait);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(hook->lockp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * let sd_start_io free the final buffer so the hook can be returned
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * first.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!done)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_put_iobuf(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * static int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * _sd_async_ea - End action for async read/write.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ARGUMENTS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * bp - io buf pointer.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * RETURNS:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * NONE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Comments:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This routine is called at interrupt level when the io is done.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is only called when the operation is asynchronous.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sd_async_ea(struct buf *bp, iob_hook_t *hook)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int done, error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We get called for each buf that completes. When they are all done.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we call the requestor's callback function.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte error = (bp->b_flags & B_ERROR) ? bp->b_error : 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_enter(hook->lockp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte done = !(--hook->count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!hook->error)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hook->error = error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mutex_exit(hook->lockp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_forw = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bp->b_back = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (done) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_off_t fba_pos;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsc_size_t fba_len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sdbc_ea_fn_t fn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte blind_t arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte arg = hook->param;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fn = hook->func;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte error = hook->error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#if defined(_SD_DEBUG) /* simulate disk errors */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (_test_async_fail == bp->b_edev) error = EIO;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* MAKE SURE b_lblkno, b_count never changes!! */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fba_pos = hook->start_fba;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fba_len = FBA_LEN(hook->size);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_put_hook(hook);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_put_iobuf(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (*fn)(arg, fba_pos, fba_len, error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sd_put_iobuf(bp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortetypedef struct ioerr_inject_s {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte dev_t ioj_dev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ioj_err;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ioj_cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte} ioerr_inject_t;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic ioerr_inject_t *ioerr_inject_table = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_ioj_load()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ioerr_inject_table =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_zalloc(sdbc_max_devs * sizeof (ioerr_inject_t), KM_SLEEP);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_ioj_unload()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ioerr_inject_table != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte kmem_free(ioerr_inject_table,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sdbc_max_devs * sizeof (ioerr_inject_t));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ioerr_inject_table = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_ioj_lookup(dev_t dev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int cd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (cd = 0; cd < sdbc_max_devs; ++cd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ioerr_inject_table[cd].ioj_dev == dev) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ioerr_inject_table[cd].ioj_cnt > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte --ioerr_inject_table[cd].ioj_cnt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ioerr_inject_table[cd].ioj_err);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_ioj_set_dev(int cd, dev_t crdev)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cd == -1) { /* all -- used for clearing table on shutdown */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < sdbc_max_devs; ++i) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ioerr_inject_table[i].ioj_dev = crdev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ioerr_inject_table[cd].ioj_dev = crdev; /* assume valid cd */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_ioj_set_err(int cd, int err, int count)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (cd == -1) { /* all */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < sdbc_max_devs; ++i) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ioerr_inject_table[i].ioj_err = err;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ioerr_inject_table[i].ioj_cnt = count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ioerr_inject_table[cd].ioj_err = err;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ioerr_inject_table[cd].ioj_cnt = count;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_ioj_clear_err(int cd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdbc_ioj_set_err(cd, 0, 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_inject_ioerr(int cd, int ioj_err, int count)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cd < -1) || (cd >= sdbc_max_devs))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdbc_ioj_set_err(cd, ioj_err, count);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte_sdbc_clear_ioerr(int cd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((cd < -1) || (cd >= sdbc_max_devs))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (EINVAL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _sdbc_ioj_clear_err(cd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif