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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * Main Transport Routine for SCSA 28 */ 29 #include <sys/scsi/scsi.h> 30 #include <sys/thread.h> 31 #include <sys/bitmap.h> 32 33 #define A_TO_TRAN(ap) ((ap)->a_hba_tran) 34 #define P_TO_TRAN(pkt) ((pkt)->pkt_address.a_hba_tran) 35 #define P_TO_ADDR(pkt) (&((pkt)->pkt_address)) 36 37 #ifdef DEBUG 38 #define SCSI_POLL_STAT 39 #endif 40 41 #ifdef SCSI_POLL_STAT 42 int scsi_poll_user; 43 int scsi_poll_intr; 44 #endif 45 46 int scsi_pkt_bad_alloc_msg = 1; 47 extern ulong_t *scsi_pkt_bad_alloc_bitmap; 48 extern kmutex_t scsi_flag_nointr_mutex; 49 extern kcondvar_t scsi_flag_nointr_cv; 50 51 extern int do_polled_io; 52 53 /* 54 * we used to set the callback_done value to NULL after the callback 55 * but this interfered with esp/fas drivers that also set the callback 56 * to NULL to prevent callbacks during error recovery 57 * to prevent confusion, create a truly unique value. 58 * The scsi_callback_done() function is used to detect a packet 59 * completion being called a second time. 60 */ 61 /* ARGSUSED */ 62 void 63 scsi_callback_done(struct scsi_pkt *pkt) 64 { 65 cmn_err(CE_PANIC, 66 "%s: duplicate scsi_callback_done() on same scsi_pkt(9s)", 67 mod_containing_pc(caller())); 68 } 69 70 #define CALLBACK_DONE (scsi_callback_done) 71 72 static void 73 scsi_flag_nointr_comp(struct scsi_pkt *pkt) 74 { 75 mutex_enter(&scsi_flag_nointr_mutex); 76 pkt->pkt_comp = CALLBACK_DONE; 77 /* 78 * We need cv_broadcast, because there can be more 79 * than one thread sleeping on the cv. We 80 * will wake all of them. The correct one will 81 * continue and the rest will again go to sleep. 82 */ 83 cv_broadcast(&scsi_flag_nointr_cv); 84 mutex_exit(&scsi_flag_nointr_mutex); 85 } 86 87 /* 88 * A packet can have FLAG_NOINTR set because of target driver or 89 * scsi_poll(). If FLAG_NOINTR is set and we are in user context, 90 * we can avoid busy waiting in HBA by replacing the callback 91 * function with our own function and resetting FLAG_NOINTR. We 92 * can't do this in interrupt context because cv_wait will 93 * sleep with CPU priority raised high and in case of some failure, 94 * the CPU will be stuck in high priority. 95 */ 96 97 int 98 scsi_transport(struct scsi_pkt *pkt) 99 { 100 struct scsi_address *ap = P_TO_ADDR(pkt); 101 int rval = TRAN_ACCEPT; 102 major_t major; 103 104 /* 105 * The DDI does not allow drivers to allocate their own scsi_pkt(9S), 106 * a driver can't have *any* compiled in dependencies on the 107 * "sizeof (struct scsi_pkt)". While this has been the case for years, 108 * many drivers have still not been fixed (or have regressed - tempted 109 * by kmem_cache_alloc()). The correct way to allocate a scsi_pkt 110 * is by calling scsi_hba_pkt_alloc(9F), or by implementing the 111 * tran_setup_pkt(9E) interfaces. 112 * 113 * The code below will identify drivers that violate this rule, and 114 * print a message. The message will identify broken drivers, and 115 * encourage getting these drivers fixed - after which this code 116 * can be removed. Getting HBA drivers fixed is important because 117 * broken drivers are an impediment to SCSA enhancement. 118 * 119 * We use the scsi_pkt_allocated_correctly() to determine if the 120 * scsi_pkt we are about to start was correctly allocated. The 121 * scsi_pkt_bad_alloc_bitmap is used to limit messages to one per 122 * driver per reboot, and with non-debug code we only check the 123 * first scsi_pkt. 124 */ 125 if (scsi_pkt_bad_alloc_msg) { 126 major = ddi_driver_major(P_TO_TRAN(pkt)->tran_hba_dip); 127 if (!BT_TEST(scsi_pkt_bad_alloc_bitmap, major) && 128 !scsi_pkt_allocated_correctly(pkt)) { 129 BT_SET(scsi_pkt_bad_alloc_bitmap, major); 130 cmn_err(CE_WARN, "%s: violates DDI scsi_pkt(9S) " 131 "allocation rules", 132 ddi_driver_name(P_TO_TRAN(pkt)->tran_hba_dip)); 133 } 134 #ifndef DEBUG 135 /* On non-debug kernel, only check the first packet */ 136 BT_SET(scsi_pkt_bad_alloc_bitmap, major); 137 #endif /* DEBUG */ 138 } 139 140 /* Some retryed packets come with this flag not cleared */ 141 pkt->pkt_flags &= ~FLAG_PKT_COMP_CALLED; 142 143 /* 144 * Check if we are required to do polled I/O. We can 145 * get scsi_pkts that don't have the FLAG_NOINTR bit 146 * set in the pkt_flags. When do_polled_io is set 147 * we will probably be at a high IPL and not get any 148 * command completion interrupts. We force polled I/Os 149 * for such packets and do a callback of the completion 150 * routine ourselves. 151 */ 152 if (!do_polled_io && ((pkt->pkt_flags & FLAG_NOINTR) == 0)) { 153 return (*A_TO_TRAN(ap)->tran_start)(ap, pkt); 154 } else if ((curthread->t_flag & T_INTR_THREAD) || do_polled_io) { 155 #ifdef SCSI_POLL_STAT 156 mutex_enter(&scsi_flag_nointr_mutex); 157 scsi_poll_intr++; 158 mutex_exit(&scsi_flag_nointr_mutex); 159 #endif 160 /* 161 * If its an interrupt thread or we already have the 162 * the FLAG_NOINTR flag set, we go ahead and call the 163 * the hba's start routine directly. We force polling 164 * only if we have do_polled_io set and FLAG_NOINTR 165 * not set. 166 */ 167 if (!do_polled_io || (pkt->pkt_flags & FLAG_NOINTR)) { 168 return ((*A_TO_TRAN(ap)->tran_start)(ap, pkt)); 169 } else { 170 uint_t savef; 171 void (*savec)(); 172 /* 173 * save the completion routine and pkt_flags 174 */ 175 savef = pkt->pkt_flags; 176 savec = pkt->pkt_comp; 177 pkt->pkt_flags |= FLAG_NOINTR; 178 pkt->pkt_comp = 0; 179 180 rval = (*A_TO_TRAN(ap)->tran_start)(ap, pkt); 181 182 /* only continue of transport accepted request */ 183 if (rval == TRAN_ACCEPT) { 184 /* 185 * Restore the pkt_completion routine 186 * and pkt flags and call the completion 187 * routine. 188 */ 189 pkt->pkt_comp = savec; 190 pkt->pkt_flags = savef; 191 scsi_hba_pkt_comp(pkt); 192 return (rval); 193 } 194 195 /* 196 * rval was not TRAN_ACCEPT -- don't want command 197 * to be retried 198 */ 199 return (TRAN_FATAL_ERROR); 200 } 201 } else { 202 uint_t savef; 203 void (*savec)(); 204 205 #ifdef SCSI_POLL_STAT 206 mutex_enter(&scsi_flag_nointr_mutex); 207 scsi_poll_user++; 208 mutex_exit(&scsi_flag_nointr_mutex); 209 #endif 210 savef = pkt->pkt_flags; 211 savec = pkt->pkt_comp; 212 213 pkt->pkt_comp = scsi_flag_nointr_comp; 214 pkt->pkt_flags &= ~FLAG_NOINTR; 215 pkt->pkt_flags |= FLAG_IMMEDIATE_CB; 216 217 if ((rval = (*A_TO_TRAN(ap)->tran_start)(ap, pkt)) == 218 TRAN_ACCEPT) { 219 mutex_enter(&scsi_flag_nointr_mutex); 220 while (pkt->pkt_comp != CALLBACK_DONE) { 221 cv_wait(&scsi_flag_nointr_cv, 222 &scsi_flag_nointr_mutex); 223 } 224 mutex_exit(&scsi_flag_nointr_mutex); 225 } 226 227 pkt->pkt_flags = savef; 228 pkt->pkt_comp = savec; 229 return (rval); 230 } 231 } 232