261 scsa1394_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
262 {
263 int instance = ddi_get_instance(dip);
264 scsa1394_state_t *sp;
265
266 switch (cmd) {
267 case DDI_ATTACH:
268 break;
269 case DDI_RESUME:
270 scsa1394_cpr_resume(dip);
271 return (DDI_SUCCESS);
272 default:
273 return (DDI_FAILURE);
274 }
275
276 if (ddi_soft_state_zalloc(scsa1394_statep, instance) != 0) {
277 return (DDI_FAILURE);
278 }
279 sp = SCSA1394_INST2STATE(instance);
280
281 #ifndef __lock_lint
282 sp->s_dip = dip;
283 sp->s_instance = instance;
284 #endif
285 mutex_init(&sp->s_mutex, NULL, MUTEX_DRIVER,
286 sp->s_attachinfo.iblock_cookie);
287 cv_init(&sp->s_event_cv, NULL, CV_DRIVER, NULL);
288
289 if (scsa1394_attach_1394(sp) != DDI_SUCCESS) {
290 scsa1394_cleanup(sp, 1);
291 return (DDI_FAILURE);
292 }
293
294 if (scsa1394_sbp2_attach(sp) != DDI_SUCCESS) {
295 scsa1394_cleanup(sp, 2);
296 return (DDI_FAILURE);
297 }
298
299 if (scsa1394_attach_threads(sp) != DDI_SUCCESS) {
300 scsa1394_cleanup(sp, 3);
301 return (DDI_FAILURE);
302 }
303
304 if (scsa1394_attach_scsa(sp) != DDI_SUCCESS) {
308
309 if (scsa1394_create_cmd_cache(sp) != DDI_SUCCESS) {
310 scsa1394_cleanup(sp, 5);
311 return (DDI_FAILURE);
312 }
313
314 if (scsa1394_add_events(sp) != DDI_SUCCESS) {
315 scsa1394_cleanup(sp, 6);
316 return (DDI_FAILURE);
317 }
318
319 /* prevent async PM changes until we are done */
320 (void) pm_busy_component(dip, 0);
321
322 /* Set power to full on */
323 (void) pm_raise_power(dip, 0, PM_LEVEL_D0);
324
325 /* we are done */
326 (void) pm_idle_component(dip, 0);
327
328 #ifndef __lock_lint
329 sp->s_dev_state = SCSA1394_DEV_ONLINE;
330 #endif
331
332 ddi_report_dev(dip);
333
334 return (DDI_SUCCESS);
335 }
336
337 static int
338 scsa1394_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
339 {
340 int instance = ddi_get_instance(dip);
341 scsa1394_state_t *sp;
342
343 if ((sp = SCSA1394_INST2STATE(instance)) == NULL) {
344 return (DDI_FAILURE);
345 }
346
347 switch (cmd) {
348 case DDI_DETACH:
349 /* Cycle power state to off and idle where done/gone */
350 (void) pm_lower_power(dip, 0, PM_LEVEL_D3);
1045 if (!scsa1394_dev_is_online(sp)) {
1046 return (SCSIPROBE_FAILURE);
1047 }
1048 lp = &sp->s_lun[sd->sd_address.a_lun];
1049
1050 if (scsa1394_probe_g0_nodata(sd, waitfunc,
1051 SCMD_TEST_UNIT_READY, 0, 0) != SCSIPROBE_EXISTS) {
1052 lp->l_nosup_tur = B_TRUE;
1053 (void) scsa1394_sbp2_reset(lp, RESET_LUN, NULL);
1054 }
1055 if (scsa1394_probe_g0_nodata(sd, waitfunc,
1056 SCMD_START_STOP, 0, 1) != SCSIPROBE_EXISTS) {
1057 lp->l_nosup_start_stop = B_TRUE;
1058 }
1059
1060 /* standard probe issues INQUIRY, which some devices may not support */
1061 if (scsi_hba_probe(sd, waitfunc) != SCSIPROBE_EXISTS) {
1062 lp->l_nosup_inquiry = B_TRUE;
1063 scsa1394_sbp2_fake_inquiry(sp, &lp->l_fake_inq);
1064 bcopy(&lp->l_fake_inq, sd->sd_inq, SUN_INQSIZE);
1065 #ifndef __lock_lint
1066 lp->l_rmb_orig = 1;
1067 #endif
1068 }
1069
1070 if (scsa1394_wrka_fake_rmb) {
1071 sd->sd_inq->inq_rmb = 1;
1072 }
1073
1074 return (SCSIPROBE_EXISTS);
1075 }
1076
1077 static int
1078 scsa1394_probe_g0_nodata(struct scsi_device *sd, int (*waitfunc)(),
1079 uchar_t cmd, uint_t addr, uint_t cnt)
1080 {
1081 struct scsi_pkt *pkt;
1082 int ret = SCSIPROBE_EXISTS;
1083
1084 pkt = scsi_init_pkt(&sd->sd_address, NULL, NULL, CDB_GROUP0,
1085 sizeof (struct scsi_arq_status), 0, PKT_CONSISTENT, waitfunc, NULL);
1086
1087 if (pkt == NULL) {
|
261 scsa1394_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
262 {
263 int instance = ddi_get_instance(dip);
264 scsa1394_state_t *sp;
265
266 switch (cmd) {
267 case DDI_ATTACH:
268 break;
269 case DDI_RESUME:
270 scsa1394_cpr_resume(dip);
271 return (DDI_SUCCESS);
272 default:
273 return (DDI_FAILURE);
274 }
275
276 if (ddi_soft_state_zalloc(scsa1394_statep, instance) != 0) {
277 return (DDI_FAILURE);
278 }
279 sp = SCSA1394_INST2STATE(instance);
280
281 sp->s_dip = dip;
282 sp->s_instance = instance;
283 mutex_init(&sp->s_mutex, NULL, MUTEX_DRIVER,
284 sp->s_attachinfo.iblock_cookie);
285 cv_init(&sp->s_event_cv, NULL, CV_DRIVER, NULL);
286
287 if (scsa1394_attach_1394(sp) != DDI_SUCCESS) {
288 scsa1394_cleanup(sp, 1);
289 return (DDI_FAILURE);
290 }
291
292 if (scsa1394_sbp2_attach(sp) != DDI_SUCCESS) {
293 scsa1394_cleanup(sp, 2);
294 return (DDI_FAILURE);
295 }
296
297 if (scsa1394_attach_threads(sp) != DDI_SUCCESS) {
298 scsa1394_cleanup(sp, 3);
299 return (DDI_FAILURE);
300 }
301
302 if (scsa1394_attach_scsa(sp) != DDI_SUCCESS) {
306
307 if (scsa1394_create_cmd_cache(sp) != DDI_SUCCESS) {
308 scsa1394_cleanup(sp, 5);
309 return (DDI_FAILURE);
310 }
311
312 if (scsa1394_add_events(sp) != DDI_SUCCESS) {
313 scsa1394_cleanup(sp, 6);
314 return (DDI_FAILURE);
315 }
316
317 /* prevent async PM changes until we are done */
318 (void) pm_busy_component(dip, 0);
319
320 /* Set power to full on */
321 (void) pm_raise_power(dip, 0, PM_LEVEL_D0);
322
323 /* we are done */
324 (void) pm_idle_component(dip, 0);
325
326 sp->s_dev_state = SCSA1394_DEV_ONLINE;
327
328 ddi_report_dev(dip);
329
330 return (DDI_SUCCESS);
331 }
332
333 static int
334 scsa1394_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
335 {
336 int instance = ddi_get_instance(dip);
337 scsa1394_state_t *sp;
338
339 if ((sp = SCSA1394_INST2STATE(instance)) == NULL) {
340 return (DDI_FAILURE);
341 }
342
343 switch (cmd) {
344 case DDI_DETACH:
345 /* Cycle power state to off and idle where done/gone */
346 (void) pm_lower_power(dip, 0, PM_LEVEL_D3);
1041 if (!scsa1394_dev_is_online(sp)) {
1042 return (SCSIPROBE_FAILURE);
1043 }
1044 lp = &sp->s_lun[sd->sd_address.a_lun];
1045
1046 if (scsa1394_probe_g0_nodata(sd, waitfunc,
1047 SCMD_TEST_UNIT_READY, 0, 0) != SCSIPROBE_EXISTS) {
1048 lp->l_nosup_tur = B_TRUE;
1049 (void) scsa1394_sbp2_reset(lp, RESET_LUN, NULL);
1050 }
1051 if (scsa1394_probe_g0_nodata(sd, waitfunc,
1052 SCMD_START_STOP, 0, 1) != SCSIPROBE_EXISTS) {
1053 lp->l_nosup_start_stop = B_TRUE;
1054 }
1055
1056 /* standard probe issues INQUIRY, which some devices may not support */
1057 if (scsi_hba_probe(sd, waitfunc) != SCSIPROBE_EXISTS) {
1058 lp->l_nosup_inquiry = B_TRUE;
1059 scsa1394_sbp2_fake_inquiry(sp, &lp->l_fake_inq);
1060 bcopy(&lp->l_fake_inq, sd->sd_inq, SUN_INQSIZE);
1061 lp->l_rmb_orig = 1;
1062 }
1063
1064 if (scsa1394_wrka_fake_rmb) {
1065 sd->sd_inq->inq_rmb = 1;
1066 }
1067
1068 return (SCSIPROBE_EXISTS);
1069 }
1070
1071 static int
1072 scsa1394_probe_g0_nodata(struct scsi_device *sd, int (*waitfunc)(),
1073 uchar_t cmd, uint_t addr, uint_t cnt)
1074 {
1075 struct scsi_pkt *pkt;
1076 int ret = SCSIPROBE_EXISTS;
1077
1078 pkt = scsi_init_pkt(&sd->sd_address, NULL, NULL, CDB_GROUP0,
1079 sizeof (struct scsi_arq_status), 0, PKT_CONSISTENT, waitfunc, NULL);
1080
1081 if (pkt == NULL) {
|