Print this page
5253 kmem_alloc/kmem_zalloc won't fail with KM_SLEEP
5254 getrbuf won't fail with KM_SLEEP


   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Enclosure Services Devices, SAF-TE Enclosure Routines
  24  *
  25  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
  26  * Use is subject to license terms.
  27  */
  28 
  29 #pragma ident   "%Z%%M% %I%     %E% SMI"
  30 
  31 #include <sys/modctl.h>
  32 #include <sys/file.h>
  33 #include <sys/scsi/scsi.h>
  34 #include <sys/stat.h>
  35 #include <sys/scsi/targets/sesio.h>
  36 #include <sys/scsi/targets/ses.h>
  37 
  38 
  39 static int set_objstat_sel(ses_softc_t *, ses_objarg *, int);
  40 static int wrbuf16(ses_softc_t *, uchar_t, uchar_t, uchar_t, uchar_t, int);
  41 static void wrslot_stat(ses_softc_t *, int);
  42 static int perf_slotop(ses_softc_t *, uchar_t, uchar_t, int);
  43 
  44 #define ALL_ENC_STAT \
  45         (ENCSTAT_CRITICAL|ENCSTAT_UNRECOV|ENCSTAT_NONCRITICAL|ENCSTAT_INFO)
  46 
  47 #define SCRATCH 64
  48 #define NPSEUDO_THERM   1
  49 #define NPSEUDO_ALARM   1
  50 struct scfg {


  95 _NOTE(DATA_READABLE_WITHOUT_LOCK(scfg::flag2))
  96 _NOTE(DATA_READABLE_WITHOUT_LOCK(scfg::pwroff))
  97 _NOTE(DATA_READABLE_WITHOUT_LOCK(scfg::slotoff))
  98 #endif
  99 
 100 static int
 101 safte_getconfig(ses_softc_t *ssc)
 102 {
 103         struct scfg *cfg;
 104         int err;
 105         Uscmd local, *lp = &local;
 106         char rqbuf[SENSE_LENGTH], *sdata;
 107         static char cdb[CDB_GROUP1] =
 108             { SCMD_READ_BUFFER, 1, SAFTE_RD_RDCFG, 0, 0, 0, 0, 0, SCRATCH, 0 };
 109 
 110         cfg = ssc->ses_private;
 111         if (cfg == NULL)
 112                 return (ENXIO);
 113 
 114         sdata = kmem_alloc(SCRATCH, KM_SLEEP);
 115         if (sdata == NULL)
 116                 return (ENOMEM);
 117 
 118         lp->uscsi_flags = USCSI_READ|USCSI_RQENABLE;
 119         lp->uscsi_timeout = ses_io_time;
 120         lp->uscsi_cdb = cdb;
 121         lp->uscsi_bufaddr = sdata;
 122         lp->uscsi_buflen = SCRATCH;
 123         lp->uscsi_cdblen = sizeof (cdb);
 124         lp->uscsi_rqbuf = rqbuf;
 125         lp->uscsi_rqlen = sizeof (rqbuf);
 126 
 127         err = ses_runcmd(ssc, lp);
 128         if (err) {
 129                 kmem_free(sdata, SCRATCH);
 130                 return (err);
 131         }
 132 
 133         if ((lp->uscsi_buflen - lp->uscsi_resid) < 6) {
 134                 SES_LOG(ssc, CE_NOTE, "Too little data (%ld) for configuration",
 135                     lp->uscsi_buflen - lp->uscsi_resid);
 136                 kmem_free(sdata, SCRATCH);


 163                 mutex_enter(&ssc->ses_devp->sd_mutex);
 164                 if (ssc->ses_nobjects) {
 165                         if (ssc->ses_objmap) {
 166                                 kmem_free(ssc->ses_objmap,
 167                                     ssc->ses_nobjects * sizeof (encobj));
 168                                 ssc->ses_objmap = NULL;
 169                         }
 170                         ssc->ses_nobjects = 0;
 171                 }
 172                 if (ssc->ses_private) {
 173                         kmem_free(ssc->ses_private, SAFTE_PRIVATE);
 174                         ssc->ses_private = NULL;
 175                 }
 176                 mutex_exit(&ssc->ses_devp->sd_mutex);
 177                 return (0);
 178         }
 179 
 180         mutex_enter(&ssc->ses_devp->sd_mutex);
 181         if (ssc->ses_private == NULL) {
 182                 ssc->ses_private = kmem_zalloc(SAFTE_PRIVATE, KM_SLEEP);
 183                 if (ssc->ses_private == NULL) {
 184                         mutex_exit(&ssc->ses_devp->sd_mutex);
 185                         return (ENOMEM);
 186                 }
 187         }
 188 
 189         ssc->ses_nobjects = 0;
 190         ssc->ses_encstat = 0;
 191         mutex_exit(&ssc->ses_devp->sd_mutex);
 192 
 193         if ((r = safte_getconfig(ssc)) != 0) {
 194                 return (r);
 195         }
 196 
 197         /*
 198          * The number of objects here, as well as that reported by the
 199          * READ_BUFFER/GET_CONFIG call, are the over-temperature flags (15)
 200          * that get reported during READ_BUFFER/READ_ENC_STATUS.
 201          */
 202         mutex_enter(&ssc->ses_devp->sd_mutex);
 203         cc = ssc->ses_private;
 204         ssc->ses_nobjects = cc->Nfans + cc->Npwr + cc->Nslots + cc->DoorLock +
 205             cc->Ntherm + cc->Nspkrs + NPSEUDO_THERM + NPSEUDO_ALARM;
 206         ssc->ses_objmap = (encobj *)




   9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  10  * or http://www.opensolaris.org/os/licensing.
  11  * See the License for the specific language governing permissions
  12  * and limitations under the License.
  13  *
  14  * When distributing Covered Code, include this CDDL HEADER in each
  15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  16  * If applicable, add the following below this CDDL HEADER, with the
  17  * fields enclosed by brackets "[]" replaced with your own identifying
  18  * information: Portions Copyright [yyyy] [name of copyright owner]
  19  *
  20  * CDDL HEADER END
  21  */
  22 /*
  23  * Enclosure Services Devices, SAF-TE Enclosure Routines
  24  *
  25  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
  26  * Use is subject to license terms.
  27  */
  28 


  29 #include <sys/modctl.h>
  30 #include <sys/file.h>
  31 #include <sys/scsi/scsi.h>
  32 #include <sys/stat.h>
  33 #include <sys/scsi/targets/sesio.h>
  34 #include <sys/scsi/targets/ses.h>
  35 
  36 
  37 static int set_objstat_sel(ses_softc_t *, ses_objarg *, int);
  38 static int wrbuf16(ses_softc_t *, uchar_t, uchar_t, uchar_t, uchar_t, int);
  39 static void wrslot_stat(ses_softc_t *, int);
  40 static int perf_slotop(ses_softc_t *, uchar_t, uchar_t, int);
  41 
  42 #define ALL_ENC_STAT \
  43         (ENCSTAT_CRITICAL|ENCSTAT_UNRECOV|ENCSTAT_NONCRITICAL|ENCSTAT_INFO)
  44 
  45 #define SCRATCH 64
  46 #define NPSEUDO_THERM   1
  47 #define NPSEUDO_ALARM   1
  48 struct scfg {


  93 _NOTE(DATA_READABLE_WITHOUT_LOCK(scfg::flag2))
  94 _NOTE(DATA_READABLE_WITHOUT_LOCK(scfg::pwroff))
  95 _NOTE(DATA_READABLE_WITHOUT_LOCK(scfg::slotoff))
  96 #endif
  97 
  98 static int
  99 safte_getconfig(ses_softc_t *ssc)
 100 {
 101         struct scfg *cfg;
 102         int err;
 103         Uscmd local, *lp = &local;
 104         char rqbuf[SENSE_LENGTH], *sdata;
 105         static char cdb[CDB_GROUP1] =
 106             { SCMD_READ_BUFFER, 1, SAFTE_RD_RDCFG, 0, 0, 0, 0, 0, SCRATCH, 0 };
 107 
 108         cfg = ssc->ses_private;
 109         if (cfg == NULL)
 110                 return (ENXIO);
 111 
 112         sdata = kmem_alloc(SCRATCH, KM_SLEEP);


 113 
 114         lp->uscsi_flags = USCSI_READ|USCSI_RQENABLE;
 115         lp->uscsi_timeout = ses_io_time;
 116         lp->uscsi_cdb = cdb;
 117         lp->uscsi_bufaddr = sdata;
 118         lp->uscsi_buflen = SCRATCH;
 119         lp->uscsi_cdblen = sizeof (cdb);
 120         lp->uscsi_rqbuf = rqbuf;
 121         lp->uscsi_rqlen = sizeof (rqbuf);
 122 
 123         err = ses_runcmd(ssc, lp);
 124         if (err) {
 125                 kmem_free(sdata, SCRATCH);
 126                 return (err);
 127         }
 128 
 129         if ((lp->uscsi_buflen - lp->uscsi_resid) < 6) {
 130                 SES_LOG(ssc, CE_NOTE, "Too little data (%ld) for configuration",
 131                     lp->uscsi_buflen - lp->uscsi_resid);
 132                 kmem_free(sdata, SCRATCH);


 159                 mutex_enter(&ssc->ses_devp->sd_mutex);
 160                 if (ssc->ses_nobjects) {
 161                         if (ssc->ses_objmap) {
 162                                 kmem_free(ssc->ses_objmap,
 163                                     ssc->ses_nobjects * sizeof (encobj));
 164                                 ssc->ses_objmap = NULL;
 165                         }
 166                         ssc->ses_nobjects = 0;
 167                 }
 168                 if (ssc->ses_private) {
 169                         kmem_free(ssc->ses_private, SAFTE_PRIVATE);
 170                         ssc->ses_private = NULL;
 171                 }
 172                 mutex_exit(&ssc->ses_devp->sd_mutex);
 173                 return (0);
 174         }
 175 
 176         mutex_enter(&ssc->ses_devp->sd_mutex);
 177         if (ssc->ses_private == NULL) {
 178                 ssc->ses_private = kmem_zalloc(SAFTE_PRIVATE, KM_SLEEP);




 179         }
 180 
 181         ssc->ses_nobjects = 0;
 182         ssc->ses_encstat = 0;
 183         mutex_exit(&ssc->ses_devp->sd_mutex);
 184 
 185         if ((r = safte_getconfig(ssc)) != 0) {
 186                 return (r);
 187         }
 188 
 189         /*
 190          * The number of objects here, as well as that reported by the
 191          * READ_BUFFER/GET_CONFIG call, are the over-temperature flags (15)
 192          * that get reported during READ_BUFFER/READ_ENC_STATUS.
 193          */
 194         mutex_enter(&ssc->ses_devp->sd_mutex);
 195         cc = ssc->ses_private;
 196         ssc->ses_nobjects = cc->Nfans + cc->Npwr + cc->Nslots + cc->DoorLock +
 197             cc->Ntherm + cc->Nspkrs + NPSEUDO_THERM + NPSEUDO_ALARM;
 198         ssc->ses_objmap = (encobj *)