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