1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * Main Transport Routine for SCSA 30 */ 31 #include <sys/scsi/scsi.h> 32 #include <sys/thread.h> 33 #include <sys/bitmap.h> 34 35 #define A_TO_TRAN(ap) ((ap)->a_hba_tran) 36 #define P_TO_TRAN(pkt) ((pkt)->pkt_address.a_hba_tran) 37 #define P_TO_ADDR(pkt) (&((pkt)->pkt_address)) 38 39 #ifdef DEBUG 40 #define SCSI_POLL_STAT 41 #endif 42 43 #ifdef SCSI_POLL_STAT 44 int scsi_poll_user; 45 int scsi_poll_intr; 46 #endif 47 48 int scsi_pkt_bad_alloc_msg = 1; 49 extern ulong_t *scsi_pkt_bad_alloc_bitmap; 50 extern kmutex_t scsi_flag_nointr_mutex; 51 extern kcondvar_t scsi_flag_nointr_cv; 52 53 extern int do_polled_io; 54 55 /* 56 * we used to set the callback_done value to NULL after the callback 57 * but this interfered with esp/fas drivers that also set the callback 58 * to NULL to prevent callbacks during error recovery 59 * to prevent confusion, create a truly unique value 60 */ 61 static int scsi_callback_done; 62 #define CALLBACK_DONE ((void (*)(struct scsi_pkt *))(&scsi_callback_done)) 63 64 static void 65 scsi_flag_nointr_comp(struct scsi_pkt *pkt) 66 { 67 mutex_enter(&scsi_flag_nointr_mutex); 68 pkt->pkt_comp = CALLBACK_DONE; 69 /* 70 * We need cv_broadcast, because there can be more 71 * than one thread sleeping on the cv. We 72 * will wake all of them. The correct one will 73 * continue and the rest will again go to sleep. 74 */ 75 cv_broadcast(&scsi_flag_nointr_cv); 76 mutex_exit(&scsi_flag_nointr_mutex); 77 } 78 79 static void 80 scsi_consistent_comp(struct scsi_pkt *pkt) 81 { 82 struct scsi_pkt_cache_wrapper *pcw = 83 (struct scsi_pkt_cache_wrapper *)pkt; 84 85 pkt->pkt_comp = pcw->pcw_orig_comp; 86 scsi_sync_pkt(pkt); 87 (*pkt->pkt_comp)(pkt); 88 } 89 90 /* 91 * A packet can have FLAG_NOINTR set because of target driver or 92 * scsi_poll(). If FLAG_NOINTR is set and we are in user context, 93 * we can avoid busy waiting in HBA by replacing the callback 94 * function with our own function and resetting FLAG_NOINTR. We 95 * can't do this in interrupt context because cv_wait will 96 * sleep with CPU priority raised high and in case of some failure, 97 * the CPU will be stuck in high priority. 98 */ 99 100 int 101 scsi_transport(struct scsi_pkt *pkt) 102 { 103 struct scsi_address *ap = P_TO_ADDR(pkt); 104 int rval = TRAN_ACCEPT; 105 major_t major; 106 107 /* 108 * The DDI does not allow drivers to allocate their own scsi_pkt(9S), 109 * a driver can't have *any* compiled in dependencies on the 110 * "sizeof (struct scsi_pkt)". While this has been the case for years, 111 * many drivers have still not been fixed (or have regressed - tempted 112 * by kmem_cache_alloc()). The correct way to allocate a scsi_pkt 113 * is by calling scsi_hba_pkt_alloc(9F), or by implementing the 114 * tran_setup_pkt(9E) interfaces. 115 * 116 * The code below will identify drivers that violate this rule, and 117 * print a message. The message will identify broken drivers, and 118 * encourage getting these drivers fixed - after which this code 119 * can be removed. Getting HBA drivers fixed is important because 120 * broken drivers are an impediment to SCSA enhancement. 121 * 122 * We use the scsi_pkt_allocated_correctly() to determine if the 123 * scsi_pkt we are about to start was correctly allocated. The 124 * scsi_pkt_bad_alloc_bitmap is used to limit messages to one per 125 * driver per reboot, and with non-debug code we only check the 126 * first scsi_pkt. 127 */ 128 if (scsi_pkt_bad_alloc_msg) { 129 major = ddi_driver_major(P_TO_TRAN(pkt)->tran_hba_dip); 130 if (!BT_TEST(scsi_pkt_bad_alloc_bitmap, major) && 131 !scsi_pkt_allocated_correctly(pkt)) { 132 BT_SET(scsi_pkt_bad_alloc_bitmap, major); 133 cmn_err(CE_WARN, "%s: violates DDI scsi_pkt(9S) " 134 "allocation rules", 135 ddi_driver_name(P_TO_TRAN(pkt)->tran_hba_dip)); 136 } 137 #ifndef DEBUG 138 /* On non-debug kernel, only check the first packet */ 139 BT_SET(scsi_pkt_bad_alloc_bitmap, major); 140 #endif /* DEBUG */ 141 } 142 143 /* determine if we need to sync the data on the HBA's behalf */ 144 if ((pkt->pkt_dma_flags & DDI_DMA_CONSISTENT) && 145 ((pkt->pkt_comp) != NULL) && 146 ((P_TO_TRAN(pkt)->tran_setup_pkt) != NULL)) { 147 struct scsi_pkt_cache_wrapper *pcw = 148 (struct scsi_pkt_cache_wrapper *)pkt; 149 150 _NOTE(SCHEME_PROTECTS_DATA("unique per pkt", \ 151 scsi_pkt_cache_wrapper::pcw_orig_comp)); 152 153 pcw->pcw_orig_comp = pkt->pkt_comp; 154 pkt->pkt_comp = scsi_consistent_comp; 155 } 156 /* 157 * Check if we are required to do polled I/O. We can 158 * get scsi_pkts that don't have the FLAG_NOINTR bit 159 * set in the pkt_flags. When do_polled_io is set 160 * we will probably be at a high IPL and not get any 161 * command completion interrupts. We force polled I/Os 162 * for such packets and do a callback of the completion 163 * routine ourselves. 164 */ 165 if (!do_polled_io && ((pkt->pkt_flags & FLAG_NOINTR) == 0)) { 166 return (*A_TO_TRAN(ap)->tran_start)(ap, pkt); 167 } else if ((curthread->t_flag & T_INTR_THREAD) || do_polled_io) { 168 #ifdef SCSI_POLL_STAT 169 mutex_enter(&scsi_flag_nointr_mutex); 170 scsi_poll_intr++; 171 mutex_exit(&scsi_flag_nointr_mutex); 172 #endif 173 /* 174 * If its an interrupt thread or we already have the 175 * the FLAG_NOINTR flag set, we go ahead and call the 176 * the hba's start routine directly. We force polling 177 * only if we have do_polled_io set and FLAG_NOINTR 178 * not set. 179 */ 180 if (!do_polled_io || (pkt->pkt_flags & FLAG_NOINTR)) { 181 return ((*A_TO_TRAN(ap)->tran_start)(ap, pkt)); 182 } else { 183 uint_t savef; 184 void (*savec)(); 185 /* 186 * save the completion routine and pkt_flags 187 */ 188 savef = pkt->pkt_flags; 189 savec = pkt->pkt_comp; 190 pkt->pkt_flags |= FLAG_NOINTR; 191 pkt->pkt_comp = 0; 192 193 rval = (*A_TO_TRAN(ap)->tran_start)(ap, pkt); 194 195 /* only continue of transport accepted request */ 196 if (rval == TRAN_ACCEPT) { 197 /* 198 * Restore the pkt_completion routine 199 * and pkt flags and call the completion 200 * routine. 201 */ 202 pkt->pkt_comp = savec; 203 pkt->pkt_flags = savef; 204 205 if (pkt->pkt_comp != NULL) { 206 (*pkt->pkt_comp)(pkt); 207 } 208 209 return (rval); 210 } 211 212 /* 213 * rval was not TRAN_ACCEPT -- don't want command 214 * to be retried 215 */ 216 return (TRAN_FATAL_ERROR); 217 } 218 } else { 219 uint_t savef; 220 void (*savec)(); 221 int status; 222 223 #ifdef SCSI_POLL_STAT 224 mutex_enter(&scsi_flag_nointr_mutex); 225 scsi_poll_user++; 226 mutex_exit(&scsi_flag_nointr_mutex); 227 #endif 228 savef = pkt->pkt_flags; 229 savec = pkt->pkt_comp; 230 231 pkt->pkt_comp = scsi_flag_nointr_comp; 232 pkt->pkt_flags &= ~FLAG_NOINTR; 233 pkt->pkt_flags |= FLAG_IMMEDIATE_CB; 234 235 if ((status = (*A_TO_TRAN(ap)->tran_start)(ap, pkt)) == 236 TRAN_ACCEPT) { 237 mutex_enter(&scsi_flag_nointr_mutex); 238 while (pkt->pkt_comp != CALLBACK_DONE) { 239 cv_wait(&scsi_flag_nointr_cv, 240 &scsi_flag_nointr_mutex); 241 } 242 mutex_exit(&scsi_flag_nointr_mutex); 243 } 244 245 pkt->pkt_flags = savef; 246 pkt->pkt_comp = savec; 247 return (status); 248 } 249 } 250