1*cbab9cadSchs /* $NetBSD: icpvar.h,v 1.13 2012/10/27 17:18:20 chs Exp $ */ 29a09578eSad 39a09578eSad /*- 4405790a8Sthorpej * Copyright (c) 2002, 2003 The NetBSD Foundation, Inc. 59a09578eSad * All rights reserved. 69a09578eSad * 79a09578eSad * This code is derived from software contributed to The NetBSD Foundation 8405790a8Sthorpej * by Andrew Doran, and by Jason R. Thorpe of Wasabi Systems, Inc. 99a09578eSad * 109a09578eSad * Redistribution and use in source and binary forms, with or without 119a09578eSad * modification, are permitted provided that the following conditions 129a09578eSad * are met: 139a09578eSad * 1. Redistributions of source code must retain the above copyright 149a09578eSad * notice, this list of conditions and the following disclaimer. 159a09578eSad * 2. Redistributions in binary form must reproduce the above copyright 169a09578eSad * notice, this list of conditions and the following disclaimer in the 179a09578eSad * documentation and/or other materials provided with the distribution. 189a09578eSad * 199a09578eSad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 209a09578eSad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 219a09578eSad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 229a09578eSad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 239a09578eSad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 249a09578eSad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 259a09578eSad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 269a09578eSad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 279a09578eSad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 289a09578eSad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 299a09578eSad * POSSIBILITY OF SUCH DAMAGE. 309a09578eSad */ 319a09578eSad 329a09578eSad #ifndef _IC_ICPVAR_H_ 339a09578eSad #define _IC_ICPVAR_H_ 349a09578eSad 3559417408Sad #include <sys/mutex.h> 3659417408Sad 37405790a8Sthorpej #include <dev/ic/icp_ioctl.h> 38405790a8Sthorpej 399a09578eSad /* 409a09578eSad * Miscellaneous constants. 419a09578eSad */ 429a09578eSad #define ICP_RETRIES 6 439a09578eSad #define ICP_WATCHDOG_FREQ 5 449a09578eSad #define ICP_BUSY_WAIT_MS 2500 459a09578eSad #define ICP_MAX_XFER 65536 46405790a8Sthorpej #define ICP_UCMD_SCRATCH_SIZE 4096 47405790a8Sthorpej #define ICP_SCRATCH_SIZE (8192 + ICP_UCMD_SCRATCH_SIZE) 489a09578eSad #define ICP_SCRATCH_SENSE \ 499b761cfdSbouyer (ICP_SCRATCH_SIZE - sizeof(struct scsi_sense_data) * (ICP_NCCBS + ICP_NCCB_RESERVE)) 50405790a8Sthorpej #define ICP_SCRATCH_UCMD (ICP_SCRATCH_SENSE - ICP_UCMD_SCRATCH_SIZE) 519a09578eSad 529a09578eSad #define ICP_NCCBS ICP_MAX_CMDS 539a09578eSad #define ICP_NCCB_RESERVE 4 549a09578eSad 559a09578eSad /* 569a09578eSad * Context structure for interrupt service. 579a09578eSad */ 589a09578eSad struct icp_intr_ctx { 599a09578eSad u_int32_t info; 609a09578eSad u_int32_t info2; 619a09578eSad u_int16_t cmd_status; 629a09578eSad u_int16_t service; 639a09578eSad u_int8_t istatus; 649a09578eSad }; 659a09578eSad 669a09578eSad /* 679a09578eSad * Command control block. 689a09578eSad */ 699a09578eSad struct icp_ccb { 709a09578eSad SIMPLEQ_ENTRY(icp_ccb) ic_chain; 719a09578eSad u_int ic_service; 729a09578eSad u_int ic_flags; 739a09578eSad u_int ic_status; 749a09578eSad u_int ic_ident; 759a09578eSad u_int ic_nsgent; 769a09578eSad u_int ic_cmdlen; 779a09578eSad u_int ic_xfer_size; 789a09578eSad bus_dmamap_t ic_xfer_map; 799a09578eSad struct icp_sg *ic_sg; 80*cbab9cadSchs device_t ic_dv; 819a09578eSad void *ic_context; 829a09578eSad void (*ic_intr)(struct icp_ccb *); 839a09578eSad struct icp_cmd ic_cmd; 849a09578eSad }; 859a09578eSad #define IC_XFER_IN 0x01 /* Map describes inbound xfer */ 869a09578eSad #define IC_XFER_OUT 0x02 /* Map describes outbound xfer */ 879a09578eSad #define IC_WAITING 0x04 /* We have waiters */ 889a09578eSad #define IC_COMPLETE 0x08 /* Command completed */ 899a09578eSad #define IC_ALLOCED 0x10 /* CCB allocated */ 90405790a8Sthorpej #define IC_UCMD 0x20 /* user ioctl */ 919a09578eSad 929a09578eSad /* 939a09578eSad * Logical drive information. 949a09578eSad */ 959a09578eSad struct icp_cachedrv { 969a09578eSad u_int cd_size; 979a09578eSad u_int cd_type; 989a09578eSad }; 999a09578eSad 1009a09578eSad /* 1013178a4f4Sthorpej * Call-backs into the service back-ends (ld for cache service, 1023178a4f4Sthorpej * icpsp for raw service). 1033178a4f4Sthorpej */ 1043178a4f4Sthorpej struct icp_servicecb { 105529e91fcScegger void (*iscb_openings)(device_t, int); 1063178a4f4Sthorpej }; 1073178a4f4Sthorpej 1083178a4f4Sthorpej /* 1099a09578eSad * Per-controller context. 1109a09578eSad */ 1119a09578eSad struct icp_softc { 112*cbab9cadSchs device_t icp_dv; 1139a09578eSad void *icp_ih; 1149a09578eSad bus_dma_tag_t icp_dmat; 1159a09578eSad bus_space_tag_t icp_dpmemt; 1169a09578eSad bus_space_handle_t icp_dpmemh; 1179a09578eSad bus_addr_t icp_dpmembase; 1189a09578eSad bus_space_tag_t icp_iot; 1199a09578eSad bus_space_handle_t icp_ioh; 1209a09578eSad bus_addr_t icp_iobase; 1219a09578eSad 1229a09578eSad int icp_class; 123405790a8Sthorpej u_int16_t icp_fw_vers; 1249a09578eSad u_int16_t icp_ic_all_size; 1259a09578eSad u_int8_t icp_bus_cnt; 1269a09578eSad u_int8_t icp_bus_id[ICP_MAXBUS]; 1279a09578eSad struct icp_cachedrv icp_cdr[ICP_MAX_HDRIVES]; 1283178a4f4Sthorpej const struct icp_servicecb *icp_servicecb[ICP_MAX_HDRIVES + ICP_MAXBUS]; 129*cbab9cadSchs device_t icp_children[ICP_MAX_HDRIVES + ICP_MAXBUS]; 1309a09578eSad int icp_ndevs; 1319a09578eSad int icp_openings; 1323178a4f4Sthorpej int icp_features; 1333178a4f4Sthorpej int icp_nchan; 1349a09578eSad 1359a09578eSad u_int32_t icp_info; 1369a09578eSad u_int32_t icp_info2; 1379a09578eSad u_int16_t icp_status; 138405790a8Sthorpej u_int16_t icp_service; 1399a09578eSad 1409a09578eSad bus_dmamap_t icp_scr_dmamap; 1419a09578eSad bus_dma_segment_t icp_scr_seg[1]; 14253524e44Schristos void * icp_scr; 1439a09578eSad 1449a09578eSad struct icp_ccb *icp_ccbs; 1459a09578eSad u_int icp_nccbs; 146405790a8Sthorpej u_int icp_flags; 1473178a4f4Sthorpej u_int icp_qfreeze; 1483178a4f4Sthorpej u_int icp_running; 1499a09578eSad SIMPLEQ_HEAD(,icp_ccb) icp_ccb_freelist; 1509a09578eSad SIMPLEQ_HEAD(,icp_ccb) icp_ccb_queue; 151405790a8Sthorpej SIMPLEQ_HEAD(,icp_ccb) icp_ucmd_queue; 1529a09578eSad struct callout icp_wdog_callout; 1539a09578eSad 154405790a8Sthorpej struct icp_ccb *icp_ucmd_ccb; 155405790a8Sthorpej 156405790a8Sthorpej /* Temporary buffer for event data. */ 157405790a8Sthorpej gdt_evt_data icp_evt; 158405790a8Sthorpej 1599a09578eSad void (*icp_copy_cmd)(struct icp_softc *, struct icp_ccb *); 1609a09578eSad u_int8_t (*icp_get_status)(struct icp_softc *); 1619a09578eSad void (*icp_intr)(struct icp_softc *, struct icp_intr_ctx *); 1629a09578eSad void (*icp_release_event)(struct icp_softc *, 1639a09578eSad struct icp_ccb *); 1649a09578eSad void (*icp_set_sema0)(struct icp_softc *); 1659a09578eSad int (*icp_test_busy)(struct icp_softc *); 166405790a8Sthorpej 167405790a8Sthorpej /* 168405790a8Sthorpej * This info is needed by the user ioctl interface needed to 169405790a8Sthorpej * support the ICP configuration tools. 170405790a8Sthorpej */ 171405790a8Sthorpej int icp_pci_bus; 172405790a8Sthorpej int icp_pci_device; 173405790a8Sthorpej int icp_pci_device_id; 174405790a8Sthorpej int icp_pci_subdevice_id; 1759a09578eSad }; 1769a09578eSad 1773178a4f4Sthorpej /* icp_features */ 1783178a4f4Sthorpej #define ICP_FEAT_CACHESERVICE 0x01 /* cache service usable */ 1793178a4f4Sthorpej #define ICP_FEAT_RAWSERVICE 0x02 /* raw service usable */ 1803178a4f4Sthorpej 181405790a8Sthorpej /* icp_flags */ 182405790a8Sthorpej #define ICP_F_WAIT_CCB 0x01 /* someone waiting for CCBs */ 1833178a4f4Sthorpej #define ICP_F_WAIT_FREEZE 0x02 /* someone waiting for qfreeze */ 184405790a8Sthorpej 185405790a8Sthorpej #define ICP_HAS_WORK(icp) \ 186405790a8Sthorpej (! SIMPLEQ_EMPTY(&(icp)->icp_ccb_queue) || \ 187405790a8Sthorpej ! SIMPLEQ_EMPTY(&(icp)->icp_ucmd_queue)) 188405790a8Sthorpej 189405790a8Sthorpej #define ICP_STAT_INCR(icp, x) \ 190405790a8Sthorpej do { \ 191405790a8Sthorpej /* XXX Globals, for now. XXX */ \ 192405790a8Sthorpej icp_stats. ## x ## _act++; \ 193405790a8Sthorpej if (icp_stats. ## x ## _act > icp_stats. ## x ## _max) \ 194405790a8Sthorpej icp_stats. ## x ## _max = icp_stats. ## x ## _act; \ 195405790a8Sthorpej } while (/*CONSTCOND*/0) 196405790a8Sthorpej 197405790a8Sthorpej #define ICP_STAT_SET(icp, x, v) \ 198405790a8Sthorpej do { \ 199405790a8Sthorpej /* XXX Globals, for now. XXX */ \ 200405790a8Sthorpej icp_stats. ## x ## _act = (v); \ 201405790a8Sthorpej if (icp_stats. ## x ## _act > icp_stats. ## x ## _max) \ 202405790a8Sthorpej icp_stats. ## x ## _max = icp_stats. ## x ## _act; \ 203405790a8Sthorpej } while (/*CONSTCOND*/0) 204405790a8Sthorpej 205405790a8Sthorpej #define ICP_STAT_DECR(icp, x) \ 206405790a8Sthorpej do { \ 207405790a8Sthorpej /* XXX Globals, for now. XXX */ \ 208405790a8Sthorpej icp_stats. ## x ## _act--; \ 209405790a8Sthorpej } while (/*CONSTCOND*/0) 210405790a8Sthorpej 2119a09578eSad #define ICP_ISA 0x01 2129a09578eSad #define ICP_EISA 0x02 2139a09578eSad #define ICP_PCI 0x03 2149a09578eSad #define ICP_PCINEW 0x04 2159a09578eSad #define ICP_MPR 0x05 2169a09578eSad #define ICP_CLASS_MASK 0x07 2179a09578eSad #define ICP_FC 0x10 2189a09578eSad #define ICP_CLASS(icp) ((icp)->icp_class & ICP_CLASS_MASK) 2199a09578eSad 2209a09578eSad int icp_init(struct icp_softc *, const char *); 2219a09578eSad int icp_intr(void *); 2229a09578eSad 223405790a8Sthorpej extern int icp_count; 224405790a8Sthorpej extern gdt_statist_t icp_stats; 225405790a8Sthorpej 2269a09578eSad /* 2279a09578eSad * Consumer interface. 2289a09578eSad */ 2299a09578eSad struct icp_attach_args { 2309a09578eSad int icpa_unit; 2319a09578eSad }; 2329a09578eSad 2339a09578eSad #define ICPA_UNIT_SCSI 100 2349a09578eSad 2359a09578eSad struct icp_ccb *icp_ccb_alloc(struct icp_softc *); 236405790a8Sthorpej struct icp_ccb *icp_ccb_alloc_wait(struct icp_softc *); 2379a09578eSad void icp_ccb_enqueue(struct icp_softc *, struct icp_ccb *); 2389a09578eSad void icp_ccb_free(struct icp_softc *, struct icp_ccb *); 2399a09578eSad int icp_ccb_map(struct icp_softc *, struct icp_ccb *, void *, int, int); 2409a09578eSad int icp_ccb_poll(struct icp_softc *, struct icp_ccb *, int); 2419a09578eSad void icp_ccb_unmap(struct icp_softc *, struct icp_ccb *); 2429a09578eSad int icp_ccb_wait(struct icp_softc *, struct icp_ccb *, int); 243405790a8Sthorpej int icp_ccb_wait_user(struct icp_softc *, struct icp_ccb *, int); 2449a09578eSad int icp_cmd(struct icp_softc *, u_int8_t, u_int16_t, u_int32_t, u_int32_t, 2459a09578eSad u_int32_t); 246405790a8Sthorpej int icp_ucmd(struct icp_softc *, gdt_ucmd_t *); 2473178a4f4Sthorpej int icp_freeze(struct icp_softc *); 2483178a4f4Sthorpej void icp_unfreeze(struct icp_softc *); 2493178a4f4Sthorpej 2503178a4f4Sthorpej void icp_rescan(struct icp_softc *, int); 2513178a4f4Sthorpej void icp_rescan_all(struct icp_softc *); 2523178a4f4Sthorpej 2533178a4f4Sthorpej void icp_register_servicecb(struct icp_softc *, int, 2543178a4f4Sthorpej const struct icp_servicecb *); 255405790a8Sthorpej 256405790a8Sthorpej gdt_evt_str *icp_store_event(struct icp_softc *, u_int16_t, u_int16_t, 257405790a8Sthorpej gdt_evt_data *); 258405790a8Sthorpej int icp_read_event(struct icp_softc *, int, gdt_evt_str *); 259405790a8Sthorpej void icp_readapp_event(struct icp_softc *, u_int8_t, gdt_evt_str *); 260405790a8Sthorpej void icp_clear_events(struct icp_softc *); 2619a09578eSad 26259417408Sad extern kmutex_t icp_ioctl_mutex; 26359417408Sad 2649a09578eSad #endif /* !_IC_ICPVAR_H_ */ 265