xref: /onnv-gate/usr/src/uts/common/io/pcmcia/pcide.c (revision 7656:2621e50fdf4a)
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 
27 
28 /*
29  * ATA  disk driver
30  *
31  * Handles the standard PCMCIA ATA interface
32  *
33  */
34 #include <sys/errno.h>
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/user.h>
38 #include <sys/buf.h>
39 #include <sys/ioctl.h>
40 #include <sys/file.h>
41 #include <sys/uio.h>
42 #include <sys/fcntl.h>
43 #include <sys/cmn_err.h>
44 #include <sys/kmem.h>
45 #include <sys/sysmacros.h>
46 #include <sys/stat.h>
47 #include <sys/scsi/scsi.h>
48 
49 #include <sys/fdio.h>
50 
51 #include <sys/errno.h>
52 #include <sys/open.h>
53 #include <sys/varargs.h>
54 #include <sys/fs/pc_label.h>
55 
56 #include <sys/hdio.h>
57 #include <sys/dkio.h>
58 #include <sys/dktp/dadkio.h>
59 
60 #include <sys/dklabel.h>
61 
62 #include <sys/vtoc.h>
63 
64 #include <sys/types.h>
65 #include <sys/conf.h>
66 #include <sys/dditypes.h>
67 #include <sys/ddi.h>
68 #include <sys/sunddi.h>
69 #include <sys/dktp/cm.h>
70 
71 #include <sys/dktp/fdisk.h>
72 
73 #include <sys/fs/pc_label.h>
74 
75 #include <sys/pctypes.h>
76 
77 
78 /*
79  * PCMCIA and DDI related header files
80  */
81 #include <sys/pccard.h>
82 
83 #include <sys/pcmcia/pcata.h>
84 
85 int	pcata_debug = 0;
86 
87 static int pcata_detach(dev_info_t *devi, ddi_detach_cmd_t cmd);
88 static int pcata_attach(dev_info_t *dip, ddi_attach_cmd_t cmd);
89 static int pcata_att1(dev_info_t *dip, ata_soft_t *softp);
90 static int pcata_go(ata_unit_t *unitp);
91 static int pcata_wait(uint32_t port, ushort_t onbits, ushort_t offbits,
92 	ata_soft_t *softp);
93 static int pcata_wait1(uint32_t port, ushort_t onbits, ushort_t offbits,
94 	int interval, ata_soft_t *softp);
95 static void pcata_wait_complete(ata_soft_t *softp);
96 static uchar_t pcata_drive_type(ata_soft_t *softp, ushort_t *secbuf);
97 static int pcata_setpar(int drive, int heads, int sectors, ata_soft_t *softp);
98 static int pcata_dump(dev_t dev, caddr_t addr, daddr_t blkno, int nblk);
99 static int pcata_print(dev_t dev, char *str);
100 static int pcata_rdrw(dev_t dev, struct uio *uio, int flag);
101 static int pcata_read(dev_t dev, struct uio *uio, cred_t *cred_p);
102 static int pcata_write(dev_t dev, struct uio *uio, cred_t *cred_p);
103 #ifdef  ATA_DEBUG
104 static void pcata_print_sttflag(int svalue);
105 #endif
106 static void pcata_clear_queues(ata_unit_t *unitp);
107 static void pcata_nack_packet(struct ata_cmpkt *pktp);
108 static void pcata_iosetup(ata_unit_t *unitp, struct ata_cmpkt *pktp);
109 static int pcata_send_data(ata_unit_t *unitp, int count);
110 static int pcata_get_data(ata_unit_t *unitp, int count);
111 
112 struct cb_ops pcata_cb_ops = {
113 		pcata_open,		/* driver open routine		*/
114 		pcata_close,		/* driver close routine		*/
115 		pcata_strategy,		/* driver strategy routine	*/
116 		pcata_print,		/* driver print routine		*/
117 		pcata_dump,		/* driver dump routine		*/
118 		pcata_read,		/* driver read routine		*/
119 		pcata_write,		/* driver write routine		*/
120 		pcata_ioctl,		/* driver ioctl routine		*/
121 		nodev,			/* driver devmap routine	*/
122 		nodev,			/* driver mmap routine		*/
123 		nodev,			/* driver segmap routine	*/
124 		nochpoll,		/* driver chpoll routine	*/
125 		pcata_prop_op,		/* driver prop_op routine	*/
126 		0,			/* driver cb_str - STREAMS only	*/
127 		D_NEW | D_MTSAFE,	/* driver compatibility flag	*/
128 	};
129 
130 static struct dev_ops ata_ops = {
131 		DEVO_REV,		/* devo_rev, */
132 		0,			/* refcnt  */
133 		pcata_getinfo,		/* info */
134 		nulldev,		/* identify */
135 		nulldev,		/* probe */
136 		pcata_attach,		/* attach */
137 		pcata_detach,		/* detach */
138 		nulldev,		/* reset */
139 		&pcata_cb_ops,		/* driver operations */
140 		NULL,			/* bus operations */
141 		NULL,			/* power */
142 		ddi_quiesce_not_needed,		/* quiesce */
143 	};
144 
145 
146 
147 void	*pcata_soft = NULL;
148 
149 
150 #include <sys/modctl.h>
151 
152 extern  struct mod_ops  mod_driverops;
153 
154 static struct modldrv modldrv = {
155 		&mod_driverops, /* Type of module. This one is a driver */
156 		"PCMCIA ATA disk controller",
157 		&ata_ops, /* driver ops */
158 	};
159 
160 static struct modlinkage modlinkage = {
161 		MODREV_1, (void *)&modldrv, NULL
162 	};
163 
164 int
_init(void)165 _init(void)
166 {
167 	int	status;
168 
169 	status = mod_install(&modlinkage);
170 	if (status)
171 		return (status);
172 
173 	status = ddi_soft_state_init(&pcata_soft, sizeof (ata_soft_t), 1);
174 
175 	return (status);
176 }
177 
178 
179 int
_fini(void)180 _fini(void)
181 {
182 	int	status;
183 
184 	status = mod_remove(&modlinkage);
185 	if (!status)
186 		ddi_soft_state_fini(&pcata_soft);
187 
188 	return (status);
189 }
190 
191 
192 int
_info(struct modinfo * modinfop)193 _info(struct modinfo *modinfop)
194 {
195 	return (mod_info(&modlinkage, modinfop));
196 }
197 
198 static int
pcata_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)199 pcata_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
200 {
201 	int		instance = ddi_get_instance(dip);
202 	ata_soft_t	*softp;
203 	int		ret;
204 
205 	/* resume from a checkpoint */
206 	if (cmd == DDI_RESUME)
207 		return (DDI_SUCCESS);
208 
209 	if (cmd != DDI_ATTACH) {
210 #ifdef  ATA_DEBUG
211 		cmn_err(CE_CONT, "_attach returning FAILURE\n");
212 #endif
213 		return (DDI_FAILURE);
214 	}
215 
216 	/* Allocate soft state associated with this instance. */
217 	ret = ddi_soft_state_zalloc(pcata_soft, ddi_get_instance(dip));
218 	if (ret != DDI_SUCCESS) {
219 #ifdef  ATA_DEBUG
220 		cmn_err(CE_CONT, "_attach: Unable to alloc state\n");
221 #endif
222 		return (DDI_FAILURE);
223 	}
224 
225 	softp = ddi_get_soft_state(pcata_soft, instance);
226 
227 #ifdef  ATA_DEBUG
228 	if (pcata_debug & DINIT)
229 		cmn_err(CE_CONT, "_attach softp=%p\n", (void *)softp);
230 #endif
231 
232 	softp->dip		= dip;
233 	softp->instance		= instance;
234 	softp->ab_dip		= dip;
235 	softp->crashbuf		= getrbuf(KM_SLEEP);
236 	softp->flags		= 0;
237 	softp->card_state	= 0;
238 	softp->intr_pending	= 0;
239 	softp->softint_pending	= 0;
240 	softp->write_in_progress = 0;
241 	softp->blk_open		= 0;
242 	softp->chr_open		= 0;
243 	softp->ejected_while_mounted = 0;
244 	bzero(softp->lyr_open, sizeof (softp->lyr_open[NUM_PARTS]));
245 
246 	/*
247 	 * Initialize to 0 until it is incremented in pcram_check_media
248 	 */
249 	softp->checkmedia_flag =  0;
250 	softp->ejected_media_flag =  0;
251 	softp->media_state = DKIO_NONE;
252 
253 	/*
254 	 * if attach fails, Solaris won't call detach
255 	 * so we call detach here to release all flagged resources
256 	 */
257 	ret = pcata_att1(dip, softp);
258 	if (ret == DDI_FAILURE) {
259 		(void) pcata_detach(dip, DDI_DETACH);
260 		return (DDI_FAILURE);
261 	}
262 
263 	return (DDI_SUCCESS);
264 }
265 
266 static int
pcata_att1(dev_info_t * dip,ata_soft_t * softp)267 pcata_att1(dev_info_t *dip, ata_soft_t *softp)
268 {
269 	int		ret;
270 	client_reg_t	client_reg;
271 	sockmask_t	sockmask;
272 	map_log_socket_t map_log_socket;
273 	cs_ddi_info_t	cs_ddi_info;
274 	get_status_t	get_status;
275 
276 
277 	/*
278 	 * create ata_mutex
279 	 */
280 	ret = ddi_get_soft_iblock_cookie(dip, DDI_SOFTINT_MED,
281 	    &softp->soft_blk_cookie);
282 	if (ret != DDI_SUCCESS) {
283 #ifdef ATA_DEBUG
284 		cmn_err(CE_CONT, "_attach: unable to get iblock cookie\n");
285 #endif
286 		return (ret);
287 	}
288 
289 
290 	/*
291 	 * Setup the mutexii and condition variables.
292 	 * Initialize the mutex that protects the ATA registers.
293 	 */
294 	mutex_init(&softp->ata_mutex, NULL, MUTEX_DRIVER,
295 	    (void *)(softp->soft_blk_cookie));
296 	mutex_init(&softp->label_mutex, NULL, MUTEX_DRIVER, NULL);
297 
298 	cv_init(&softp->readywait_cv, NULL, CV_DRIVER, NULL);
299 	/* for DKIOCSTATE ioctl()  */
300 	cv_init(&softp->condvar_mediastate, NULL, CV_DRIVER, NULL);
301 	softp->flags |= PCATA_DIDLOCKS;
302 
303 
304 	/*
305 	 * link in soft interrupt
306 	 */
307 	ret = ddi_add_softintr(dip, DDI_SOFTINT_MED, &softp->softint_id,
308 	    NULL, NULL, pcata_intr, (caddr_t)softp);
309 	if (ret != DDI_SUCCESS) {
310 #ifdef ATA_DEBUG
311 		cmn_err(CE_CONT, "_attach: unable to get soft interrupt\n");
312 #endif
313 		return (DDI_FAILURE);
314 	}
315 	softp->flags |= PCATA_SOFTINTROK;
316 
317 
318 	/*
319 	 * Register with Card Services
320 	 */
321 	client_reg.Attributes =
322 	    INFO_IO_CLIENT | INFO_CARD_SHARE | INFO_CARD_EXCL;
323 
324 	client_reg.EventMask =
325 	    CS_EVENT_CARD_INSERTION |
326 	    CS_EVENT_CARD_REMOVAL |
327 	    CS_EVENT_CARD_REMOVAL_LOWP |
328 	    CS_EVENT_PM_RESUME |
329 	    CS_EVENT_CLIENT_INFO |
330 	    CS_EVENT_PM_SUSPEND |
331 	    CS_EVENT_REGISTRATION_COMPLETE;
332 
333 	client_reg.event_handler = (csfunction_t *)pcata_event;
334 	client_reg.event_callback_args.client_data = softp;
335 	client_reg.Version = _VERSION(2, 1);
336 	client_reg.dip = dip;
337 	(void) strcpy(client_reg.driver_name, pcata_name);
338 
339 	ret = csx_RegisterClient(&softp->client_handle, &client_reg);
340 	if (ret != CS_SUCCESS) {
341 #ifdef  ATA_DEBUG
342 		cmn_err(CE_CONT, "_attach RegisterClient failed %s\n",
343 		    pcata_CS_etext(ret));
344 #endif
345 		return (DDI_FAILURE);
346 	}
347 
348 	mutex_init(&softp->event_hilock, NULL, MUTEX_DRIVER,
349 	    *(client_reg.iblk_cookie));
350 
351 	softp->flags |= PCATA_REGCLIENT;
352 
353 
354 	/*
355 	 * Get logical socket number and store in softp struct
356 	 */
357 	ret = csx_MapLogSocket(softp->client_handle, &map_log_socket);
358 	if (ret != CS_SUCCESS) {
359 #ifdef  ATA_DEBUG
360 		cmn_err(CE_CONT, "_attach: MapLogSocket failed %s\n",
361 		    pcata_CS_etext(ret));
362 #endif
363 		return (DDI_FAILURE);
364 	}
365 	softp->sn = map_log_socket.PhySocket;
366 
367 
368 	/*
369 	 *
370 	 */
371 	cs_ddi_info.Socket	= softp->sn;
372 	cs_ddi_info.driver_name = pcata_name;
373 	cs_ddi_info.dip		= dip;
374 	cs_ddi_info.instance	= softp->instance;
375 	if ((ret = csx_CS_DDI_Info(&cs_ddi_info)) != CS_SUCCESS) {
376 #ifdef  ATA_DEBUG
377 		cmn_err(CE_CONT, "_attach: socket %d CS_DDI_Info failed %s\n",
378 		    softp->sn, pcata_CS_etext(ret));
379 #endif
380 		return (DDI_FAILURE);
381 	}
382 
383 	/*
384 	 * After the RequestSocketMask call, we start receiving events
385 	 */
386 	sockmask.EventMask = CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL;
387 	ret = csx_RequestSocketMask(softp->client_handle, &sockmask);
388 	if (ret != CS_SUCCESS) {
389 #ifdef  ATA_DEBUG
390 		cmn_err(CE_CONT, "_attach: RequestSocketMask failed %s\n",
391 		    pcata_CS_etext(ret));
392 #endif
393 		return (DDI_FAILURE);
394 	}
395 	softp->flags |= PCATA_REQSOCKMASK;
396 
397 	/*
398 	 * We may not get the CARD_READY event
399 	 * until after we leave this function.
400 	 */
401 	mutex_enter(&softp->event_hilock);
402 	softp->card_state |= PCATA_READY_WAIT;
403 	mutex_exit(&softp->event_hilock);
404 
405 	(void) csx_GetStatus(softp->client_handle, &get_status);
406 	if (get_status.raw_CardState & CS_STATUS_CARD_INSERTED) {
407 
408 		/* wait for drive to be initialized */
409 		(void) pcata_readywait(softp);
410 
411 		if ((softp->card_state & PCATA_CARD_INSERTED) == 0 ||
412 		    (softp->flags & PCATA_READY) == 0) {
413 
414 			mutex_enter(&softp->ata_mutex);
415 			mutex_enter(&softp->event_hilock);
416 
417 			softp->card_state &= ~PCATA_READY_WAIT;
418 
419 			mutex_exit(&softp->event_hilock);
420 			mutex_exit(&softp->ata_mutex);
421 		}
422 	}
423 
424 	/*
425 	 * Wait for minor node creation before returning
426 	 */
427 	pcata_minor_wait(softp);
428 
429 	/*
430 	 * print banner to announce device
431 	 */
432 	ddi_report_dev(dip);
433 
434 	return (DDI_SUCCESS);
435 }
436 
437 static int
pcata_detach(dev_info_t * devi,ddi_detach_cmd_t cmd)438 pcata_detach(dev_info_t *devi, ddi_detach_cmd_t cmd)
439 {
440 	int	instance = ddi_get_instance(devi);
441 	ata_soft_t *softp;
442 	int	ret;
443 
444 	if (cmd == DDI_SUSPEND)
445 		return (DDI_SUCCESS);
446 
447 	if (cmd != DDI_DETACH)
448 		return (DDI_FAILURE);
449 
450 	softp = ddi_get_soft_state(pcata_soft, instance);
451 
452 
453 	/*
454 	 * Call the card_removal routine to do any final card cleanup
455 	 */
456 	if (CARD_PRESENT_VALID(softp)) {
457 		(void) pcata_card_removal(softp, CS_EVENT_PRI_LOW);
458 	}
459 
460 
461 	/*
462 	 * Release our socket mask - note that we can't do much
463 	 * if we fail these calls other than to note that
464 	 * the system will probably panic shortly.  Perhaps
465 	 * we should fail the detach in the case where these
466 	 * CS calls fail?
467 	 */
468 
469 	if (softp->flags & PCATA_REQSOCKMASK) {
470 		release_socket_mask_t rsm;
471 		ret = csx_ReleaseSocketMask(softp->client_handle, &rsm);
472 		if (ret != CS_SUCCESS) {
473 #ifdef ATA_DEBUG
474 			cmn_err(CE_CONT, "_detach "
475 			    "ReleaseSocketMask failed %s\n",
476 			    pcata_CS_etext(ret));
477 #endif
478 		}
479 	}
480 
481 
482 	/*
483 	 * Deregister with Card Services - we will stop getting
484 	 * events at this point.
485 	 */
486 	if (softp->flags & PCATA_REGCLIENT) {
487 		ret = csx_DeregisterClient(softp->client_handle);
488 		if (ret != CS_SUCCESS) {
489 #ifdef ATA_DEBUG
490 			cmn_err(CE_CONT, "_detach: "
491 			    "DeregisterClient failed %s\n",
492 			    pcata_CS_etext(ret));
493 #endif
494 			return (DDI_FAILURE);
495 
496 		}
497 		softp->flags &= ~PCATA_REGCLIENT;
498 	}
499 
500 
501 	/* unregister the softintrrupt handler */
502 	if (softp->flags & PCATA_SOFTINTROK) {
503 		ddi_remove_softintr(softp->softint_id);
504 		softp->flags &= ~PCATA_SOFTINTROK;
505 
506 	}
507 
508 	if (softp->flags & PCATA_DIDLOCKS) {
509 
510 		/*
511 		 * XXX/lcl make sure no threads are blocked
512 		 */
513 		mutex_destroy(&softp->ata_mutex);
514 		mutex_destroy(&softp->event_hilock);
515 		mutex_destroy(&softp->label_mutex);
516 		cv_destroy(&softp->readywait_cv);
517 		/* for DKIOCSTATE ioctl()  */
518 		cv_destroy(&softp->condvar_mediastate);
519 		softp->flags &= ~PCATA_DIDLOCKS;
520 	}
521 
522 	/* Free various structures and memory here. */
523 	if (softp && softp->crashbuf)
524 		freerbuf(softp->crashbuf);
525 
526 	/* Free the soft state structure here */
527 	ddi_soft_state_free(pcata_soft, instance);
528 
529 #ifdef ATA_DEBUG
530 	if (pcata_debug & DPCM)
531 		cmn_err(CE_NOTE, "successful detach\n");
532 #endif
533 
534 	return (DDI_SUCCESS);
535 }
536 
537 
538 /*
539  *	Common controller object interface
540  */
541 /*
542  * initiate a new I/O request
543  * either start it or add it to the request queue
544  */
545 int
pcata_start(ata_unit_t * unitp,buf_t * bp,int blkno)546 pcata_start(ata_unit_t *unitp, buf_t *bp, int blkno)
547 {
548 	ata_soft_t	*softp = unitp->a_blkp;
549 	struct ata_cmpkt *pktp;
550 	int		ret;
551 	int		kf = 0;
552 
553 	ASSERT(mutex_owned(&softp->ata_mutex));
554 
555 #ifdef ATA_DEBUG
556 	if (pcata_debug & DENT) {
557 		cmn_err(CE_CONT, "_start unitp=%p, bp=%p bp->b_private=%p\n",
558 		    (void *)unitp,
559 		    (void *)bp,
560 		    bp->b_private);
561 	}
562 #endif
563 
564 	if (!CARD_PRESENT_VALID(softp))
565 		return (CTL_SEND_FAILURE);
566 
567 	/* XXX/lcl why is this different from CARD_PRESENT_VALID */
568 	if (softp->ab_status_flag & ATA_OFFLINE) {
569 		return (CTL_SEND_FAILURE);
570 	}
571 
572 	pktp = (struct ata_cmpkt *)kmem_zalloc(sizeof (*pktp),  kf);
573 	if (!pktp) {
574 		cmn_err(CE_NOTE, "_start kmem_zalloc failed\n");
575 		return (CTL_SEND_FAILURE);
576 	}
577 
578 #ifdef ATA_DEBUG
579 	if (pcata_debug & DENT)
580 		cmn_err(CE_CONT, "_start pktp=%p\n", (void *)pktp);
581 #endif
582 
583 	if ((bp->b_flags & B_PAGEIO) || (bp->b_flags & B_PHYS))
584 		bp_mapin(bp);
585 
586 	pktp->ac_bytes_per_block = unitp->au_bytes_per_block;
587 	pktp->ac_start_v_addr	= bp->b_un.b_addr;	/* xfer address */
588 	pktp->cp_bytexfer	= bp->b_bcount;
589 	pktp->cp_bp		= bp;
590 	pktp->cp_ctl_private	= unitp;
591 	pktp->cp_srtsec		= blkno;
592 
593 	if (bp->b_flags & B_READ) {
594 		pktp->ac_direction	= AT_IN;
595 		pktp->ac_cdb		= DCMD_READ;
596 	} else {
597 		pktp->ac_direction	= AT_OUT;
598 		pktp->ac_cdb		= DCMD_WRITE;
599 	}
600 
601 	/*
602 	 * b_private is set to 0xBEE by pcata_buf_setup
603 	 * which is called by an ioctl DIOCTL_RWCMD with a subcommand
604 	 * of either DADKIO_RWCMD_READ or DADKIO_RWCMD_WRITE
605 	 *
606 	 * these commands are used to do I/O through the IOCTL interface
607 	 *
608 	 * b_back contains a pointer to the ioctl packet struct (dadkio_rwcmd)
609 	 */
610 	if (bp->b_private == (void *)0xBEE)
611 		pktp->cp_passthru = bp->b_back;
612 
613 #ifdef ATA_DEBUG
614 	if (pcata_debug & DIO) {
615 		cmn_err(CE_CONT, "passthru command seen: 0x%p\n",
616 		    pktp->cp_passthru);
617 	}
618 #endif
619 
620 	pcata_iosetup(unitp, pktp);	/* fill a packet */
621 	pktp->pkt_forw = 0;
622 
623 #ifdef ATA_DEBUG
624 	if (pcata_debug & DIO) {
625 		cmn_err(CE_CONT, "_start: active: %c  head: %c\n",
626 		    (softp->ab_active == NULL ? 'N' : 'Y'),
627 		    (softp->ab_head == NULL ? 'N' : 'Y'));
628 	}
629 #endif
630 
631 	if (softp->ab_active == NULL) {
632 		/*
633 		 * The controller is idle.
634 		 * Put the packet in ab_active....
635 		 */
636 		softp->ab_active = pktp;
637 		/*
638 		 * ... and start it off
639 		 */
640 		ret = PCATA_GO_RETRY;
641 		while (ret ==  PCATA_GO_RETRY) {
642 			ret = pcata_go(unitp);
643 		}
644 		if (ret == DDI_FAILURE) {
645 			cmn_err(CE_NOTE, "start_cmd failure \n");
646 			softp->ab_active = NULL;
647 			return (CTL_SEND_FAILURE);
648 		}
649 
650 	} else {
651 		/*
652 		 * the controller is busy now so put the packet
653 		 * on ab_head or ab_last.
654 		 */
655 
656 		if (softp->ab_head == NULL)
657 			softp->ab_head = pktp;
658 		else
659 			softp->ab_last->pkt_forw = pktp;
660 
661 		softp->ab_last = pktp;
662 	}
663 
664 	return (CTL_SEND_SUCCESS);
665 }
666 
667 
668 /*
669  * initiate I/O for packet linked on ab_active
670  */
671 static int
pcata_go(ata_unit_t * unitp)672 pcata_go(ata_unit_t *unitp)
673 {
674 	ata_soft_t	*softp = unitp->a_blkp;
675 	struct ata_cmpkt *pktp = softp->ab_active;
676 	uint32_t	nbytes;
677 	uint32_t	start_sec;
678 	uint32_t	cyl;
679 	uint32_t	resid;
680 	uchar_t		head;
681 	uchar_t		drvheads;
682 	uchar_t		drvsectors;
683 
684 	uchar_t		ac_devctl;
685 	uchar_t		ac_sec;
686 	uchar_t		ac_count;
687 	uchar_t		ac_lwcyl;
688 	uchar_t		ac_hicyl;
689 	uchar_t		ac_hd;
690 
691 	ASSERT(mutex_owned(&softp->ata_mutex));
692 
693 	if (pktp == NULL)
694 		return (DDI_SUCCESS);
695 
696 	if (!CARD_PRESENT_VALID(softp)) {
697 		pktp->ac_scb	= DERR_ABORT;
698 		pktp->cp_reason	= CPS_CHKERR;
699 		return (DDI_FAILURE);
700 	}
701 
702 #ifdef ATA_DEBUG
703 	if (pcata_debug & DENT) {
704 		cmn_err(CE_CONT, "_go (%p) altstatus %x error %x\n",
705 		    (void *)unitp,
706 		    csx_Get8(softp->handle, AT_ALTSTATUS),
707 		    csx_Get8(softp->handle, AT_ERROR));
708 		cmn_err(CE_CONT, "_go handle=%p\n", softp->handle);
709 	}
710 #endif
711 
712 	/*
713 	 * calculate drive address based on pktp->cp_srtsec
714 	 */
715 	start_sec	= pktp->cp_srtsec;
716 	drvheads	= unitp->au_hd;
717 	drvsectors	= unitp->au_sec;
718 	resid		= start_sec / drvsectors;
719 	head		= resid % drvheads;
720 	cyl		= resid / drvheads;
721 	nbytes		= min(pktp->cp_resid, pktp->ac_bytes_per_block);
722 	ac_count	= (nbytes >> SCTRSHFT);
723 	ac_devctl	= unitp->au_ctl_bits;
724 	ac_sec		= (start_sec % drvsectors) + 1;
725 	ac_hd		= head | unitp->au_drive_bits;
726 	ac_lwcyl	= cyl;
727 	ac_hicyl	= (cyl >> 8);
728 
729 #ifdef ATA_DEBUG
730 	if (pcata_debug & DIO) {
731 		cmn_err(CE_CONT,
732 		    "_go %s at lba=%d (%uc %uh %us) "
733 		    "%d sectors cmd=%x ctl=%x\n",
734 		    (pktp->ac_direction == AT_OUT) ? "WT" : "RD",
735 		    start_sec, cyl, head, ac_sec,
736 		    ac_count,
737 		    pktp->ac_cmd, ac_devctl);
738 	}
739 #endif
740 
741 	if (pcata_wait(AT_ALTSTATUS, ATS_DRDY, ATS_BSY, softp))
742 		return (DDI_FAILURE);
743 
744 	pcata_wait_complete(softp);
745 
746 	PCIDE_OUTB(softp->handle, AT_DEVCTL, ac_devctl);
747 	PCIDE_OUTB(softp->handle, AT_SECT, ac_sec);
748 	PCIDE_OUTB(softp->handle, AT_COUNT, ac_count);
749 	PCIDE_OUTB(softp->handle, AT_LCYL, ac_lwcyl);
750 	PCIDE_OUTB(softp->handle, AT_HCYL, ac_hicyl);
751 	PCIDE_OUTB(softp->handle, AT_DRVHD, ac_hd);
752 
753 	/*
754 	 * the command should make the controller status show BSY
755 	 * the ISR intr_hi will not record status while the controller is BSY
756 	 * therefore set interrupt expected state now
757 	 * the next time we receive an interrupt and the controller is not BSY
758 	 * the ISR will do the right thing
759 	 */
760 
761 	mutex_enter(&softp->hi_mutex);
762 	softp->intr_pending++;
763 	if (pktp->ac_direction == AT_OUT)
764 		softp->write_in_progress++;
765 	csx_Put8(softp->handle, AT_CMD, pktp->ac_cmd);
766 	mutex_exit(&softp->hi_mutex);
767 
768 	/*
769 	 * If there's data to go along with the command, send it now.
770 	 */
771 	if (pktp->ac_direction == AT_OUT) {
772 		if (pcata_send_data(unitp, nbytes) == DDI_FAILURE) {
773 			if (pktp->cp_retry >= RETRY_CNT) {
774 				pcata_clear_queues(unitp);
775 				return (DDI_FAILURE);
776 			} else {
777 				pktp->cp_retry++;
778 				cmn_err(CE_CONT, "_go: write failure,"
779 				    " retry=%d \n", pktp->cp_retry);
780 				cmn_err(CE_CONT,
781 				    "_go at lba=%d (%uc %uh %us) "
782 				    "%d sectors cmd=%x ctl=%x \n",
783 				    start_sec, cyl, head, ac_sec,
784 				    ac_count,
785 				    pktp->ac_cmd, ac_devctl);
786 				return (PCATA_GO_RETRY);
787 			}
788 		}
789 	}
790 
791 	return (DDI_SUCCESS);
792 }
793 
794 /*
795  * return value
796  *	success means go on o next block
797  *	failure means continue with current block
798  */
799 static void
pcata_iocmpl(ata_soft_t * softp)800 pcata_iocmpl(ata_soft_t *softp)
801 {
802 	struct ata_cmpkt *pktp;
803 	ata_unit_t	*unitp;
804 	int		nbytes;
805 	int		ret;
806 	uchar_t		status;
807 	uchar_t		error;
808 
809 	ASSERT(mutex_owned(&softp->ata_mutex));
810 
811 	if (!CARD_PRESENT_VALID(softp)) {
812 		cmn_err(CE_CONT, "?_iocmpl Device not present\n");
813 		return;
814 	}
815 
816 	pktp = softp->ab_active;
817 
818 	error = pktp->ac_error;
819 	status = pktp->ac_status;
820 
821 	unitp = (ata_unit_t *)pktp->cp_ctl_private;
822 
823 	/*
824 	 * If there was an error, quit now
825 	 * XXX/lcl no retry is attempted?
826 	 */
827 	if ((status & ATS_ERR) || (error & ATE_ABORT)) {
828 #ifdef ATA_DEBUG
829 		if (pcata_debug & DIO)
830 			cmn_err(CE_CONT,
831 			    "_iocmpl I/O error status=%04x error=%04x\n",
832 			    status,
833 			    error);
834 #endif
835 		pktp->cp_reason = CPS_CHKERR;
836 		return;
837 	}
838 
839 	nbytes = min(pktp->cp_resid, pktp->ac_bytes_per_block);
840 
841 	if (pktp->ac_direction == AT_IN) {
842 		/*
843 		 * do the read of the block
844 		 */
845 		ret = pcata_get_data(unitp, nbytes);
846 		if (ret == DDI_FAILURE) {
847 			/*
848 			 * If the controller never presented the data
849 			 * and the error bit isn't set,
850 			 * there's a real problem.  Kill it now.
851 			 */
852 			pcata_clear_queues(unitp);
853 			return;
854 		}
855 	}
856 
857 	/*
858 	 * update counts...
859 	 */
860 	pktp->ac_v_addr += nbytes;
861 	pktp->cp_resid -= nbytes;
862 	pktp->cp_reason = CPS_SUCCESS;
863 	pktp->cp_srtsec	+= (nbytes >> SCTRSHFT);
864 
865 	/* If last command was a GET_DEFECTS delay a bit */
866 	if (pktp->ac_cmd == ATC_READDEFECTS)
867 		drv_usecwait(1000);
868 }
869 
870 int
pcata_intr_hi(ata_soft_t * softp)871 pcata_intr_hi(ata_soft_t *softp)
872 {
873 	/*
874 	 * In ata there is no hardware support to tell if the interrupt
875 	 * belongs to ata or not. So no checks necessary here.  Later
876 	 * will check the buffer and see if we have started a transaction.
877 	 */
878 
879 	int		rval		= DDI_INTR_UNCLAIMED;
880 	struct ata_cmpkt *pktp;
881 	uchar_t		status;
882 	uchar_t		error;
883 
884 #ifdef ATA_DEBUG
885 	if (pcata_debug & DENT) {
886 		cmn_err(CE_CONT,
887 		    "_intr_hi  sn=%d status=%x intr_pending=%d "
888 		    "softint_pending=%d wr_in_prog=%d\n",
889 		    softp->sn, csx_Get8(softp->handle, AT_ALTSTATUS),
890 		    softp->intr_pending, softp->softint_pending,
891 		    softp->write_in_progress);
892 	}
893 #endif
894 	mutex_enter(&softp->hi_mutex);
895 
896 	/*
897 	 * this test is not redundant (don't remove it)
898 	 * it is part of card removal processing
899 	 * and prevents losing interrupt threads
900 	 */
901 	if (!CARD_PRESENT_VALID(softp)) {
902 		mutex_exit(&softp->hi_mutex);
903 		return (rval);
904 	}
905 
906 	status = csx_Get8(softp->handle, AT_ALTSTATUS);
907 
908 	/*
909 	 * this is a shared interrupt
910 	 * if the controller is NOT busy,
911 	 *   and an interrupt is expected
912 	 */
913 
914 	if ((status & ATS_ERR) &&
915 	    ((status & ATS_BSY) == 0) &&
916 	    (softp->intr_pending > 0)) {
917 		cmn_err(CE_CONT,
918 		    "?_intr_hi  sn=%d status=%x\n",
919 		    softp->sn, status);
920 		/* handle aborted commands */
921 		error = csx_Get8(softp->handle, AT_ERROR);
922 		if ((error & ATE_ABORT) &&
923 		    (softp->write_in_progress > 0)) {
924 			softp->write_in_progress = 0;
925 		}
926 	}
927 
928 	if ((status & ATS_BSY) == 0 &&
929 	    (softp->write_in_progress == 0) &&
930 	    (softp->intr_pending > 0)) {
931 		/*
932 		 * Read the status register,
933 		 * this clears an interrupt from the ata device
934 		 */
935 		status = csx_Get8(softp->handle, AT_STATUS);
936 		error = csx_Get8(softp->handle, AT_ERROR);
937 		rval = DDI_INTR_CLAIMED;
938 		softp->intr_pending--;
939 		/*
940 		 * Make sure the interrupt is cleared, occasionally it is not
941 		 * cleared by the first status read.
942 		 */
943 		status = csx_Get8(softp->handle, AT_STATUS);
944 		/* put the error status in the right place */
945 		if ((pktp = softp->ab_active) != 0) {
946 			pktp->ac_error = error;
947 			pktp->ac_status = status;
948 		}
949 	}
950 	mutex_exit(&softp->hi_mutex);
951 
952 #ifdef ATA_DEBUG
953 	if (pcata_debug & DENT)
954 		cmn_err(CE_CONT,
955 		    "_intr_hi status=%x error=%x claimed=%d pending=%d\n",
956 		    status, error,
957 		    (rval == DDI_INTR_CLAIMED),
958 		    softp->intr_pending);
959 #endif
960 
961 	if ((rval == DDI_INTR_CLAIMED) &&
962 	    (softp->ab_active != NULL)) {
963 		mutex_enter(&softp->hi_mutex);
964 		softp->softint_pending++;
965 		mutex_exit(&softp->hi_mutex);
966 		ddi_trigger_softintr(softp->softint_id);
967 	}
968 
969 	return (rval);
970 }
971 
972 uint32_t
pcata_intr(char * parm)973 pcata_intr(char *parm)
974 {
975 	ata_soft_t	*softp = (ata_soft_t *)parm;
976 	ata_unit_t	*unitp;
977 	struct ata_cmpkt *pktp;
978 	buf_t		*bp;
979 	uint32_t	nbytes;
980 	uint32_t	start_sec;
981 	uint32_t	cyl;
982 	uint32_t	resid;
983 	uchar_t		head;
984 	uchar_t		drvheads;
985 	uchar_t		drvsectors;
986 	uchar_t		ac_devctl;
987 	uchar_t		ac_sec;
988 	uchar_t		ac_count;
989 	int		ret;
990 
991 #ifdef ATA_DEBUG
992 	if (pcata_debug & DENT) {
993 		cmn_err(CE_CONT, "_intr entry (%p) sn=%d softint_pending=%d\n",
994 		    (void *)softp, softp->sn, softp->softint_pending);
995 	}
996 #endif
997 
998 
999 	if (softp->softint_pending == 0) {
1000 		return (DDI_INTR_UNCLAIMED);
1001 	}
1002 
1003 	mutex_enter(&softp->ata_mutex);
1004 
1005 	if (softp->ab_active == NULL) {
1006 		cmn_err(CE_CONT, "?_intr No outstanding I/O\n");
1007 		goto done;
1008 	}
1009 
1010 	/* perform I/O completion */
1011 	pcata_iocmpl(softp);
1012 
1013 	if (!CARD_PRESENT_VALID(softp))
1014 		goto done;
1015 
1016 	/*
1017 	 * if packet is done (either errors or all bytes transfered)
1018 	 *	pktp points to current packet
1019 	 *	ab_active is cleared
1020 	 * else
1021 	 *	pktp is null
1022 	 *	ab_active is unchanged
1023 	 */
1024 	pktp = softp->ab_active;
1025 	if (pktp != NULL) {
1026 		if (pktp->cp_resid == 0 || pktp->cp_reason != CPS_SUCCESS) {
1027 #ifdef ATA_DEBUG
1028 			if (pcata_debug & DENT) {
1029 				cmn_err(CE_CONT, "_intr retry=%d reason=%d"
1030 				    " CPS_SUCCESS=%d pkpt=%p cp_resid = %d\n",
1031 				    pktp->cp_retry, pktp->cp_reason,
1032 				    CPS_SUCCESS, (void *)pktp,
1033 				    pktp->cp_resid);
1034 			}
1035 #endif
1036 			if ((pktp->cp_retry < RETRY_CNT) &&
1037 			    (pktp->cp_reason != CPS_SUCCESS)) {
1038 				pktp->cp_retry++;
1039 				unitp = softp->ab_active->cp_ctl_private;
1040 
1041 				/*
1042 				 * calculate drive address based on
1043 				 * pktp->cp_srtsec
1044 				 */
1045 				start_sec = pktp->cp_srtsec;
1046 				drvheads = unitp->au_hd;
1047 				drvsectors = unitp->au_sec;
1048 				resid = start_sec / drvsectors;
1049 				head = resid % drvheads;
1050 				cyl = resid / drvheads;
1051 				nbytes = min(pktp->cp_resid,
1052 				    pktp->ac_bytes_per_block);
1053 				ac_count = (nbytes >> SCTRSHFT);
1054 				ac_devctl = unitp->au_ctl_bits;
1055 				ac_sec = (start_sec % drvsectors) + 1;
1056 
1057 				cmn_err(CE_CONT, "_intr I/O failure,"
1058 				    " retry %d\n", pktp->cp_retry);
1059 				cmn_err(CE_CONT,
1060 				    "_intr %s at lba=%d (%uc %uh %us) "
1061 				    "%d sectors cmd=%x ctl=%x\n",
1062 				    (pktp->ac_direction == AT_OUT) ?
1063 				    "write" : "read",
1064 				    start_sec, cyl, head, ac_sec,
1065 				    ac_count,
1066 				    pktp->ac_cmd, ac_devctl);
1067 
1068 				pktp = 0;
1069 			} else {
1070 				/* I/O is complete or an error has occured */
1071 				softp->ab_active = NULL;
1072 			}
1073 		} else {
1074 			/* I/O is still in progress */
1075 			pktp = 0;
1076 		}
1077 	}
1078 
1079 	/*
1080 	 * packet which caused this interrupt is now complete
1081 	 */
1082 	if (pktp) {
1083 		if ((pktp->ac_status & ATS_ERR) || (pktp->ac_error)) {
1084 			bioerror(pktp->cp_bp, EIO);
1085 #ifdef  ATA_DEBUG
1086 			cmn_err(CE_NOTE, "_intr ATA ERROR status=%x error=%x\n",
1087 			    pktp->ac_status, pktp->ac_error);
1088 #endif
1089 		}
1090 
1091 		bp =  pktp->cp_bp;
1092 		bp->b_resid = bp->b_bcount - pktp->cp_bytexfer;
1093 
1094 		/* release the thread for the I/O just completed */
1095 		biodone(bp);
1096 
1097 		kmem_free((void *)pktp, sizeof (*pktp));
1098 	}
1099 
1100 
1101 	/* if ab_active is NULL attempt to dequeue next I/O request */
1102 	if (softp->ab_active == NULL && softp->ab_head != NULL) {
1103 		softp->ab_active = softp->ab_head;
1104 		softp->ab_head = softp->ab_head->pkt_forw;
1105 
1106 #ifdef ATA_DEBUG
1107 		if (pcata_debug & DIO) {
1108 			cmn_err(CE_CONT,
1109 			    "_start_next_cmd current:%p head:%p\n",
1110 			    (void *)softp->ab_active,
1111 			    (void *)softp->ab_head);
1112 		}
1113 #endif
1114 	}
1115 
1116 	mutex_enter(&softp->hi_mutex);
1117 	softp->softint_pending--;
1118 	mutex_exit(&softp->hi_mutex);
1119 
1120 	/* if ab_active is not NULL, attempt to initiate I/O */
1121 	if (softp->ab_active != NULL) {
1122 		unitp = softp->ab_active->cp_ctl_private;
1123 
1124 		ret = PCATA_GO_RETRY;
1125 		while (ret == PCATA_GO_RETRY) {
1126 			ret = pcata_go(unitp);
1127 		}
1128 	}
1129 	goto exit;
1130 
1131 done:
1132 	mutex_enter(&softp->hi_mutex);
1133 	softp->softint_pending--;
1134 	mutex_exit(&softp->hi_mutex);
1135 exit:
1136 	mutex_exit(&softp->ata_mutex);
1137 #ifdef ATA_DEBUG
1138 	if (pcata_debug & DENT)
1139 		cmn_err(CE_CONT, "_intr exit (%p)\n", (void *)softp);
1140 #endif
1141 	return (DDI_INTR_CLAIMED);
1142 }
1143 
1144 
1145 /*
1146  * XXX/lcl need determine if all drives or a single drive is to be cleared
1147  * if all drives then eliminate tests for pktp->cp_ctl_private == unitp
1148  * if single drive then examine usage of flag ATA_OFFLINE
1149  */
1150 static void
pcata_clear_queues(ata_unit_t * unitp)1151 pcata_clear_queues(ata_unit_t *unitp)
1152 {
1153 	ata_soft_t	*softp = unitp->a_blkp;
1154 	struct ata_cmpkt *pktp;
1155 	buf_t		*bp;
1156 
1157 	ASSERT(mutex_owned(&softp->ata_mutex));
1158 
1159 #ifdef ATA_DEBUG
1160 	if (pcata_debug & DENT) {
1161 		cmn_err(CE_CONT, "_clear_queues (%p)\n", (void *)unitp);
1162 	}
1163 #endif
1164 	/*
1165 	 * nack the active request
1166 	 */
1167 	softp->ab_status_flag |= ATA_OFFLINE;
1168 
1169 	pktp = softp->ab_active;
1170 	if (pktp && pktp->cp_ctl_private == unitp)
1171 		pcata_nack_packet(pktp);
1172 
1173 	/*
1174 	 * now nack all queued requests
1175 	 */
1176 	for (pktp = softp->ab_head; pktp; pktp = pktp->pkt_forw) {
1177 		bp =  pktp->cp_bp;
1178 		if (bp && ((bp->b_flags & B_DONE) == 0)) {
1179 			if ((pktp->ac_status & ATS_ERR) || (pktp->ac_error)) {
1180 				bioerror(bp, EIO);
1181 			}
1182 
1183 			/* release the thread for the I/O */
1184 			biodone(bp);
1185 		}
1186 		if (pktp->cp_ctl_private == unitp)
1187 			pcata_nack_packet(pktp);
1188 	}
1189 }
1190 
1191 static void
pcata_nack_packet(struct ata_cmpkt * pktp)1192 pcata_nack_packet(struct ata_cmpkt *pktp)
1193 {
1194 #ifdef ATA_DEBUG
1195 	if (pcata_debug & DENT)
1196 		cmn_err(CE_CONT, "pcata_nack_packet (%p)\n", (void *)pktp);
1197 #endif
1198 	if (pktp != NULL) {
1199 		pktp->cp_reason = CPS_CHKERR;
1200 		pktp->ac_scb = DERR_ABORT;
1201 	}
1202 }
1203 
1204 /*
1205  * pcata_wait --  wait for a register of a controller to achieve a
1206  *		specific state.  Arguments are a mask of bits we care about,
1207  *		and two sub-masks.  To return normally, all the bits in the
1208  *		first sub-mask must be ON, all the bits in the second sub-
1209  *		mask must be OFF.  If 5 seconds pass without the controller
1210  *		achieving the desired bit configuration, we return 1, else
1211  *		0.
1212  */
1213 static int
pcata_wait(uint32_t port,ushort_t onbits,ushort_t offbits,ata_soft_t * softp)1214 pcata_wait(uint32_t port, ushort_t onbits, ushort_t offbits, ata_soft_t *softp)
1215 {
1216 	register int	i;
1217 	register ushort_t maskval;
1218 	int	ival = csx_Get8(softp->handle, port);
1219 
1220 	for (i = 400000; i && (CARD_PRESENT_VALID(softp)); i--) {
1221 		maskval = csx_Get8(softp->handle, port);
1222 		if (((maskval & onbits) == onbits) &&
1223 		    ((maskval & offbits) == 0))
1224 			return (0);
1225 		drv_usecwait(10);
1226 	}
1227 #ifdef ATA_DEBUG
1228 	cmn_err(CE_CONT, "_wait timeout: "
1229 	    "sn=%d port=%x on: 0x%x off: 0x%x ival: 0x%x  eval: 0x%x\n",
1230 	    softp->sn, port, onbits, offbits, ival, maskval);
1231 #endif
1232 	return (1);
1233 }
1234 
1235 
1236 /*
1237  * Similar to pcata_wait but the timeout is much shorter.  It is only used
1238  * during initialization when long delays are noticable.
1239  */
1240 static int
pcata_wait1(uint32_t port,ushort_t onbits,ushort_t offbits,int interval,ata_soft_t * softp)1241 pcata_wait1(uint32_t port, ushort_t onbits, ushort_t offbits, int interval,
1242 		ata_soft_t *softp)
1243 {
1244 	register int	i;
1245 	register ushort_t maskval;
1246 
1247 	for (i = interval; i && (CARD_PRESENT_VALID(softp)); i--) {
1248 		maskval = csx_Get8(softp->handle, port);
1249 		if (((maskval & onbits) == onbits) &&
1250 		    ((maskval & offbits) == 0))
1251 			return (0);
1252 		drv_usecwait(10);
1253 	}
1254 	return (1);
1255 }
1256 
1257 /*
1258  * Wait until the command interrupt has been serviced before starting
1259  * another command.
1260  *
1261  */
1262 static void
pcata_wait_complete(ata_soft_t * softp)1263 pcata_wait_complete(ata_soft_t *softp)
1264 {
1265 	int	i;
1266 
1267 	for (i = 0; i < PCATA_WAIT_CNT &&
1268 	    ((softp->intr_pending > 0) || (softp->softint_pending > 0)); i++) {
1269 		drv_usecwait(10);
1270 	}
1271 }
1272 
1273 static int
pcata_send_data(ata_unit_t * unitp,int count)1274 pcata_send_data(ata_unit_t *unitp, int count)
1275 {
1276 	ata_soft_t	*softp = unitp->a_blkp;
1277 	struct ata_cmpkt *pktp = unitp->a_blkp->ab_active;
1278 
1279 #ifdef ATA_DEBUG
1280 	if (pcata_debug & DENT) {
1281 		cmn_err(CE_CONT, "_send_data (%p, %x)\n",
1282 		    (void *)unitp, count);
1283 	}
1284 #endif
1285 	if (pcata_wait(AT_ALTSTATUS, ATS_DRQ, 0, softp)) {
1286 		cmn_err(CE_CONT, "_send_data - NOT READY\n");
1287 		mutex_enter(&softp->hi_mutex);
1288 		softp->write_in_progress = 0;
1289 		mutex_exit(&softp->hi_mutex);
1290 		return (DDI_FAILURE);
1291 	}
1292 
1293 	/*
1294 	 * copy count bytes from pktp->v_addr to the data port
1295 	 */
1296 #ifdef ATA_DEBUG
1297 	if (pcata_debug & DIO) {
1298 		cmn_err(CE_CONT, "_send_data: port=%x addr=0x%p count=0x%x\n",
1299 		    unitp->a_blkp->ab_data,
1300 		    (void *)pktp->ac_v_addr,
1301 		    count);
1302 	}
1303 #endif
1304 
1305 	if (!CARD_PRESENT_VALID(softp)) {
1306 		mutex_enter(&softp->hi_mutex);
1307 		softp->write_in_progress = 0;
1308 		mutex_exit(&softp->hi_mutex);
1309 		return (DDI_FAILURE);
1310 	}
1311 
1312 	mutex_enter(&softp->hi_mutex);
1313 	csx_RepPut16(softp->handle, (ushort_t *)pktp->ac_v_addr, AT_DATA,
1314 	    (count >> 1), DDI_DEV_NO_AUTOINCR);
1315 	if (softp->write_in_progress > 0)
1316 		softp->write_in_progress--;
1317 	mutex_exit(&softp->hi_mutex);
1318 
1319 #ifdef ATA_DEBUG
1320 	if (pcata_debug & DIO) {
1321 		cmn_err(CE_CONT, "_send_data: ");
1322 		pcata_print_sttflag(csx_Get8(softp->handle, AT_ALTSTATUS));
1323 	}
1324 
1325 #endif
1326 	return (DDI_SUCCESS);
1327 }
1328 
1329 
1330 static int
pcata_get_data(ata_unit_t * unitp,int count)1331 pcata_get_data(ata_unit_t *unitp, int count)
1332 {
1333 	ata_soft_t	*softp = unitp->a_blkp;
1334 	register struct ata_cmpkt *pktp = unitp->a_blkp->ab_active;
1335 
1336 	if (pcata_wait(AT_ALTSTATUS, ATS_DRQ, 0, softp)) {
1337 		cmn_err(CE_CONT, "_get_data - NOT READY\n");
1338 		return (DDI_FAILURE);
1339 	}
1340 	/*
1341 	 * copy count bytes from the data port to pktp->ac_v_addr
1342 	 */
1343 
1344 #ifdef ATA_DEBUG
1345 	if (pcata_debug & DIO) {
1346 		cmn_err(CE_CONT, "_get_data port=%x addr=0x%p count=0x%x\n",
1347 		    unitp->a_blkp->ab_data, (void *)pktp->ac_v_addr, count);
1348 	}
1349 #endif
1350 
1351 	if (!CARD_PRESENT_VALID(softp))
1352 		return (DDI_FAILURE);
1353 
1354 	csx_RepGet8(softp->handle, (uchar_t *)pktp->ac_v_addr,
1355 	    AT_DATA, count, DDI_DEV_NO_AUTOINCR);
1356 
1357 #ifdef ATA_DEBUG
1358 	if (pcata_debug & DIO)
1359 		cmn_err(CE_CONT, "_get_data complete\n");
1360 #endif
1361 	return (DDI_SUCCESS);
1362 }
1363 
1364 
1365 int
pcata_getedt(ata_soft_t * softp,int dmax)1366 pcata_getedt(ata_soft_t *softp, int dmax)
1367 {
1368 	ushort_t *secbuf;
1369 	struct atarpbuf	*rpbp;
1370 	int drive, dcount;
1371 	char buf[41];
1372 	int i;
1373 
1374 #ifdef ATA_DEBUG
1375 	if (pcata_debug & DENT) {
1376 		cmn_err(CE_CONT, "_getedt (%p)\n", (void *)softp);
1377 	}
1378 #endif
1379 	/* toggle reset bit to trigger a software reset		*/
1380 	if (!(CARD_PRESENT_VALID(softp)))
1381 		return (DDI_FAILURE);
1382 	csx_Put8(softp->handle, AT_DEVCTL, AT_DEVCTL_D3|AT_SRST);
1383 
1384 	drv_usecwait(1000);
1385 	if (!(CARD_PRESENT_VALID(softp)))
1386 		return (DDI_FAILURE);
1387 
1388 	/*
1389 	 * The interrupt disable command does not work reliably with
1390 	 * all PC ATA cards. It is better to leave interupts enabled
1391 	 * and process them as they occur.
1392 	 */
1393 
1394 	PCIDE_OUTB(softp->handle, AT_DEVCTL, ENABLE_INTERRUPT);
1395 
1396 	secbuf = (ushort_t *)kmem_zalloc(NBPSCTR, KM_NOSLEEP);
1397 	if (!secbuf) {
1398 		return (DDI_FAILURE);
1399 	}
1400 
1401 	for (dcount = drive = 0; drive < dmax; drive++) {
1402 		if (!(rpbp = (struct atarpbuf *)kmem_zalloc(
1403 		    (sizeof (struct atarpbuf) +
1404 				sizeof (struct scsi_inquiry)), KM_NOSLEEP))) {
1405 			kmem_free(secbuf, NBPSCTR);
1406 			return (DDI_FAILURE);
1407 		}
1408 
1409 		/*
1410 		 * load up with the drive number
1411 		 */
1412 		if (drive == 0) {
1413 			PCIDE_OUTB(softp->handle, AT_DRVHD, ATDH_DRIVE0);
1414 		} else {
1415 			PCIDE_OUTB(softp->handle, AT_DRVHD, ATDH_DRIVE1);
1416 		}
1417 		PCIDE_OUTB(softp->handle, AT_FEATURE, 0);
1418 
1419 		softp->ab_dev_type[drive] = pcata_drive_type(softp, secbuf);
1420 
1421 		if (softp->ab_dev_type[drive] == ATA_DEV_NONE) {
1422 			kmem_free(rpbp, (sizeof (struct atarpbuf) +
1423 			    sizeof (struct scsi_inquiry)));
1424 			continue;
1425 		}
1426 		dcount++;
1427 		bcopy((caddr_t)secbuf, (caddr_t)rpbp, sizeof (struct atarpbuf));
1428 
1429 		mutex_enter(&softp->ata_mutex);
1430 		if (!(softp->card_state & PCATA_CARD_INSERTED)) {
1431 			kmem_free(rpbp, (sizeof (struct atarpbuf) +
1432 			    sizeof (struct scsi_inquiry)));
1433 			dcount--;
1434 			mutex_exit(&softp->ata_mutex);
1435 			break;
1436 		}
1437 
1438 		softp->ab_rpbp[drive] = rpbp;
1439 
1440 		/*
1441 		 * We need to swap the strings on both platforms.
1442 		 */
1443 #ifdef _BIG_ENDIAN
1444 		pcata_byte_swap((char *)rpbp, sizeof (*rpbp));
1445 #else
1446 		pcata_byte_swap(rpbp->atarp_drvser,
1447 		    sizeof (rpbp->atarp_drvser));
1448 		pcata_byte_swap(rpbp->atarp_fw, sizeof (rpbp->atarp_fw));
1449 		pcata_byte_swap(rpbp->atarp_model, sizeof (rpbp->atarp_model));
1450 #endif
1451 
1452 		mutex_exit(&softp->ata_mutex);
1453 
1454 #ifdef	ATA_DEBUG
1455 		if (pcata_debug & DINIT) {
1456 			(void) strncpy(buf,
1457 			    rpbp->atarp_model, sizeof (rpbp->atarp_model));
1458 		buf[sizeof (rpbp->atarp_model)-1] = '\0';
1459 
1460 		/* truncate model */
1461 		for (i = sizeof (rpbp->atarp_model) - 2; i && buf[i] == ' ';
1462 		    i--) {
1463 			buf[i] = '\0';
1464 		}
1465 		cmn_err(CE_CONT, "_getedt model %s, targ %d, stat %x, err %x\n",
1466 		    buf,
1467 		    drive,
1468 		    csx_Get8(softp->handle, AT_STATUS),
1469 		    csx_Get8(softp->handle, AT_ERROR));
1470 		cmn_err(CE_CONT, "	cfg 0x%x, cyl %d, hd %d, sec/trk %d\n",
1471 		    rpbp->atarp_config,
1472 		    rpbp->atarp_fixcyls,
1473 		    rpbp->atarp_heads,
1474 		    rpbp->atarp_sectors);
1475 		cmn_err(CE_CONT, "	mult1 0x%x, mult2 0x%x, dwcap 0x%x,"
1476 		    " cap 0x%x\n",
1477 		    rpbp->atarp_mult1,
1478 		    rpbp->atarp_mult2,
1479 		    rpbp->atarp_dwcap,
1480 		    rpbp->atarp_cap);
1481 		cmn_err(CE_CONT, "	piomode 0x%x, dmamode 0x%x,"
1482 		    " advpiomode 0x%x\n",
1483 		    rpbp->atarp_piomode,
1484 		    rpbp->atarp_dmamode,
1485 		    rpbp->atarp_advpiomode);
1486 		cmn_err(CE_CONT, "	minpio %d, minpioflow %d",
1487 		    rpbp->atarp_minpio,
1488 		    rpbp->atarp_minpioflow);
1489 		cmn_err(CE_CONT, " valid 0x%x, dwdma 0x%x\n",
1490 		    rpbp->atarp_validinfo,
1491 		    rpbp->atarp_dworddma);
1492 		}
1493 #endif
1494 
1495 		if (!(CARD_PRESENT_VALID(softp)))
1496 			return (DDI_FAILURE);
1497 		(void) csx_Get8(softp->handle, AT_STATUS);
1498 		(void) csx_Get8(softp->handle, AT_ERROR);
1499 	}
1500 
1501 	kmem_free(secbuf, NBPSCTR);
1502 	if (dcount == 0)
1503 		return (DDI_FAILURE);
1504 
1505 	for (dcount = drive = 0; drive < dmax; drive++) {
1506 
1507 		if ((rpbp = softp->ab_rpbp[drive]) == NULL) {
1508 			continue; /* no drive here */
1509 		}
1510 
1511 		if (softp->ab_dev_type[drive] != ATA_DEV_DISK) {
1512 			cmn_err(CE_CONT, "Unknown IDE attachment at 0x%x.\n",
1513 			    softp->ab_cmd - AT_CMD);
1514 			continue;
1515 		}
1516 
1517 		/*
1518 		 * feed some of the info back in a set_params call.
1519 		 */
1520 		mutex_enter(&softp->ata_mutex);
1521 		if (pcata_setpar(drive, rpbp->atarp_heads,
1522 		    rpbp->atarp_sectors, softp)
1523 		    == DDI_FAILURE) {
1524 			/*
1525 			 * there should have been a drive here but it
1526 			 * didn't respond properly. It stayed BUSY.
1527 			 */
1528 			if (softp->ab_rpbp[drive]) {
1529 				kmem_free(rpbp,
1530 				    (sizeof (struct atarpbuf) +
1531 				    sizeof (struct scsi_inquiry)));
1532 			}
1533 			softp->ab_rpbp[drive] = NULL;
1534 			softp->ab_dev_type[drive] = ATA_DEV_NONE;
1535 			mutex_exit(&softp->ata_mutex);
1536 			continue;
1537 		}
1538 		mutex_exit(&softp->ata_mutex);
1539 		dcount++;
1540 	}
1541 
1542 #ifdef ATA_DEBUG
1543 	if (pcata_debug)
1544 		cmn_err(CE_CONT, "**** probed %d device%s 0x%x\n",
1545 		    dcount, dcount == 1 ? "." : "s.",
1546 		    softp->ab_cmd - AT_CMD);
1547 #endif
1548 
1549 	return (dcount ? DDI_SUCCESS : DDI_FAILURE);
1550 }
1551 
1552 /*
1553  * pcata_drive_type()
1554  */
1555 static uchar_t
pcata_drive_type(ata_soft_t * softp,ushort_t * buf)1556 pcata_drive_type(ata_soft_t *softp, ushort_t *buf)
1557 {
1558 	struct atarpbuf	*rpbp = (struct atarpbuf *)buf;
1559 
1560 	if (pcata_wait1(AT_ALTSTATUS,
1561 	    (ATS_DRDY | ATS_DSC), (ATS_BSY | ATS_ERR), 100000, softp))
1562 		return (ATA_DEV_NONE);
1563 
1564 	pcata_wait_complete(softp);
1565 
1566 	/*
1567 	 * note: pcata_drive_type is only called by pcata_getedt()
1568 	 * the drive (master/slave) is selected there
1569 	 */
1570 	/* command also known as IDENTIFY DEVICE */
1571 	mutex_enter(&softp->hi_mutex);
1572 	softp->intr_pending++;
1573 	csx_Put8(softp->handle, AT_CMD, ATC_READPARMS);
1574 	mutex_exit(&softp->hi_mutex);
1575 
1576 	if (pcata_wait1(AT_ALTSTATUS, ATS_DRQ, ATS_BSY, 1000000, softp)) {
1577 
1578 #ifdef ATA_DEBUG
1579 		if (pcata_debug) {
1580 			cmn_err(CE_NOTE, "failed drive did not settle:");
1581 			pcata_print_sttflag(csx_Get8(softp->handle, AT_STATUS));
1582 		}
1583 #endif
1584 		return (ATA_DEV_NONE);
1585 	}
1586 
1587 	csx_RepGet16(softp->handle, (ushort_t *)buf, AT_DATA, NBPSCTR >> 1,
1588 	    DDI_DEV_NO_AUTOINCR);
1589 
1590 #ifdef ATA_DEBUG
1591 	if (pcata_debug) {
1592 		if ((csx_Get8(softp->handle, AT_STATUS) & ATS_ERR) == 0) {
1593 			pcata_byte_swap(rpbp->atarp_model,
1594 			    sizeof (rpbp->atarp_model));
1595 			rpbp->atarp_model[sizeof (rpbp->atarp_model)-1] = '\0';
1596 			cmn_err(CE_CONT, "succeeded: %s\n",
1597 			    rpbp->atarp_model);
1598 			pcata_byte_swap(rpbp->atarp_model,
1599 			    sizeof (rpbp->atarp_model));
1600 		} else {
1601 			cmn_err(CE_CONT, "failed drive drive read error.\n");
1602 		}
1603 	}
1604 #endif
1605 
1606 	/*
1607 	 * wait for the drive to recognize I've read all the data.  some
1608 	 * drives have been observed to take as much as 3msec to finish
1609 	 * sending the data; allow 5 msec just in case.
1610 	 */
1611 	if (pcata_wait1(AT_ALTSTATUS, ATS_DRDY, ATS_BSY | ATS_DRQ, 500, softp))
1612 		return (ATA_DEV_NONE);
1613 
1614 	if (!CARD_PRESENT_VALID(softp))
1615 		return (ATA_DEV_NONE);
1616 
1617 	if (csx_Get8(softp->handle, AT_ALTSTATUS) & ATS_ERR)
1618 		return (ATA_DEV_NONE);
1619 
1620 	return (ATA_DEV_DISK);
1621 }
1622 
1623 
1624 /*
1625  * Drive set params command.
1626  */
1627 static int
pcata_setpar(int drive,int heads,int sectors,ata_soft_t * softp)1628 pcata_setpar(int drive, int heads, int sectors, ata_soft_t *softp)
1629 {
1630 
1631 #ifdef ATA_DEBUG
1632 	if (pcata_debug & DINIT)
1633 		cmn_err(CE_CONT, "_setpar status=0x%x drive=%d heads=%d\n",
1634 		    csx_Get8(softp->handle, AT_STATUS), drive, heads);
1635 #endif
1636 	if (!CARD_PRESENT_VALID(softp))
1637 		return (DDI_FAILURE);
1638 
1639 	if (pcata_wait(AT_ALTSTATUS, ATS_DRDY, ATS_BSY, softp))
1640 		return (DDI_FAILURE);
1641 
1642 	pcata_wait_complete(softp);
1643 
1644 	PCIDE_OUTB(softp->handle, AT_DRVHD, (heads - 1) |
1645 	    (drive == 0 ? ATDH_DRIVE0 : ATDH_DRIVE1));
1646 	PCIDE_OUTB(softp->handle, AT_COUNT, sectors);
1647 
1648 	mutex_enter(&softp->hi_mutex);
1649 	softp->intr_pending++;
1650 	csx_Put8(softp->handle, AT_CMD, ATC_SETPARAM);
1651 	mutex_exit(&softp->hi_mutex);
1652 
1653 	if (pcata_wait(AT_ALTSTATUS, 0, ATS_BSY, softp))
1654 		return (DDI_FAILURE);
1655 	return (DDI_SUCCESS);
1656 }
1657 
1658 void
pcata_byte_swap(char * buf,int n)1659 pcata_byte_swap(char *buf, int n)
1660 {
1661 	int	i;
1662 	char	c;
1663 
1664 	n &= ~1;
1665 	for (i = 0; i < n; i += 2) {
1666 		c = buf[i];
1667 		buf[i] = buf[i + 1];
1668 		buf[i + 1] = c;
1669 	}
1670 }
1671 
1672 
1673 int
pcata_set_rw_multiple(ata_soft_t * softp,int drive)1674 pcata_set_rw_multiple(ata_soft_t *softp, int drive)
1675 {
1676 	int	i;
1677 	int	laststat;
1678 	char	size;
1679 	char	accepted_size = -1;
1680 
1681 #ifdef ATA_DEBUG
1682 	if (pcata_debug & DENT) {
1683 		cmn_err(CE_CONT, "_set_rw_multiple (%p, %d)\n",
1684 		    (void *)softp, drive);
1685 	}
1686 #endif
1687 
1688 	if (!CARD_PRESENT_VALID(softp))
1689 		return (DDI_FAILURE);
1690 	/*
1691 	 * Assume we're going to use read/write multiple until the controller
1692 	 * says it doesn't understand them.
1693 	 */
1694 	softp->ab_rd_cmd[drive] = ATC_RDMULT;
1695 	softp->ab_wr_cmd[drive] = ATC_WRMULT;
1696 
1697 	/*
1698 	 * set drive number
1699 	 */
1700 	PCIDE_OUTB(softp->handle, AT_DRVHD, drive == 0 ? ATDH_DRIVE0 :
1701 	    ATDH_DRIVE1);
1702 
1703 	for (size = 32; size > 0 && accepted_size == -1 &&
1704 	    CARD_PRESENT_VALID(softp); size >>= 1) {
1705 
1706 		if (pcata_wait(AT_ALTSTATUS, ATS_DRDY, ATS_BSY, softp))
1707 			return (DDI_FAILURE);
1708 
1709 		pcata_wait_complete(softp);
1710 
1711 		/*
1712 		 * send the command
1713 		 */
1714 		PCIDE_OUTB(softp->handle, AT_COUNT, size);
1715 
1716 		mutex_enter(&softp->hi_mutex);
1717 		softp->intr_pending++;
1718 		csx_Put8(softp->handle, AT_CMD, ATC_SETMULT);
1719 		mutex_exit(&softp->hi_mutex);
1720 
1721 		if (pcata_wait(AT_ALTSTATUS, 0, ATS_BSY, softp))
1722 			/*
1723 			 * there should have been a drive here but it
1724 			 * didn't respond properly. It stayed BUSY.
1725 			 * complete failure!
1726 			 */
1727 			return (DDI_FAILURE);
1728 		/*
1729 		 * Wait for DRDY or error status
1730 		 */
1731 		for (i = 0; i < ATA_LOOP_CNT && CARD_PRESENT_VALID(softp);
1732 		    i++) {
1733 			if (((laststat = csx_Get8(softp->handle, AT_ALTSTATUS))
1734 			    & (ATS_DRDY | ATS_ERR)) != 0)
1735 				break;
1736 			drv_usecwait(10);
1737 		}
1738 		if (i == ATA_LOOP_CNT)
1739 			/*
1740 			 * Didn't get ready OR error...  complete failure!
1741 			 * there should have been a drive here but it
1742 			 * didn't respond properly. It didn't set ERR or DRQ.
1743 			 */
1744 			return (DDI_FAILURE);
1745 
1746 		/*
1747 		 * See if DRQ or error
1748 		 */
1749 		if (laststat & ATS_ERR) {
1750 			/*
1751 			 * there should have been a drive here but it
1752 			 * didn't respond properly. There was an error.
1753 			 * Try the next value.
1754 			 */
1755 			continue;
1756 		}
1757 		/*
1758 		 * Got ready.. use the value that worked.
1759 		 */
1760 		accepted_size = size;
1761 	}
1762 	if (accepted_size == -1) {
1763 		/*
1764 		 * None of the values worked...
1765 		 * the controller responded correctly though so it probably
1766 		 * doesn't support the read/write multiple commands.
1767 		 */
1768 
1769 #ifdef ATA_DEBUG
1770 		if (pcata_debug & DENT) {
1771 			cmn_err(CE_CONT, "Using STD R/W cmds and setting"
1772 			    "block factor to 1\n");
1773 		}
1774 #endif
1775 		softp->ab_rd_cmd[drive] = ATC_RDSEC;
1776 		softp->ab_wr_cmd[drive] = ATC_WRSEC;
1777 		softp->ab_block_factor[drive] = 1;
1778 		softp->ab_max_transfer = 1;
1779 		return (DDI_SUCCESS);
1780 	}
1781 	if (accepted_size == 1) {
1782 		/*
1783 		 * OK... Leave it at 1
1784 		 */
1785 #ifdef ATA_DEBUG
1786 		if (pcata_debug & DENT) {
1787 			cmn_err(CE_CONT, "setting block factor to 1\n");
1788 		}
1789 #endif
1790 		softp->ab_block_factor[drive] = accepted_size;
1791 		softp->ab_max_transfer = accepted_size;
1792 		return (DDI_SUCCESS);
1793 	}
1794 	accepted_size >>= 1;
1795 	/*
1796 	 * Allow a user specified block factor to override the system chosen
1797 	 * value.  Only allow the user to reduce the value.
1798 	 * -1 indicates the user didn't specify anything
1799 	 */
1800 	if ((softp->ab_block_factor[drive] != -1) &&
1801 	    (softp->ab_block_factor[drive] < accepted_size))
1802 		accepted_size = softp->ab_block_factor[drive];
1803 
1804 	if (pcata_wait(AT_ALTSTATUS, ATS_DRDY, ATS_BSY, softp))
1805 		return (DDI_FAILURE);
1806 
1807 	pcata_wait_complete(softp);
1808 
1809 	PCIDE_OUTB(softp->handle, AT_COUNT, accepted_size);
1810 
1811 	mutex_enter(&softp->hi_mutex);
1812 	softp->intr_pending++;
1813 	csx_Put8(softp->handle, AT_CMD, ATC_SETMULT);
1814 	mutex_exit(&softp->hi_mutex);
1815 
1816 	if (pcata_wait(AT_ALTSTATUS, 0, ATS_BSY, softp))
1817 		/*
1818 		 * there should have been a drive here but it
1819 		 * didn't respond properly. It stayed BUSY.
1820 		 */
1821 		return (DDI_FAILURE);
1822 
1823 #ifdef ATA_DEBUG
1824 	if (pcata_debug & DENT) {
1825 		cmn_err(CE_CONT, "setting block factor for drive %d to %d\n",
1826 		    drive, accepted_size);
1827 	}
1828 #endif
1829 
1830 	softp->ab_block_factor[drive] = accepted_size;
1831 	return (DDI_SUCCESS);
1832 }
1833 
1834 static int
pcata_dump(dev_t dev,caddr_t addr,daddr_t blkno,int nblk)1835 pcata_dump(dev_t dev, caddr_t addr, daddr_t blkno, int nblk)
1836 {
1837 	ata_soft_t *softp;
1838 	buf_t *bp;
1839 	void *instance;
1840 
1841 
1842 	if (pcata_getinfo(NULL, DDI_INFO_DEVT2INSTANCE, (void *)dev,
1843 	    &instance) != DDI_SUCCESS)
1844 		return (ENODEV);
1845 
1846 	softp = ddi_get_soft_state(pcata_soft, (int)(uintptr_t)instance);
1847 	if (!softp) {
1848 		return (ENXIO);
1849 	}
1850 
1851 	if (!CARD_PRESENT_VALID(softp))
1852 		return (ENODEV);
1853 
1854 	bp = softp->crashbuf;
1855 	bp->b_un.b_addr = addr;
1856 	bp->b_edev = dev;
1857 	bp->b_dev = cmpdev(dev);
1858 	bp->b_bcount = nblk * DEV_BSIZE;
1859 	bp->b_flags |= B_WRITE | B_PHYS;
1860 	bp->b_blkno = blkno;
1861 	bp->b_private = 0;
1862 
1863 	/*
1864 	 * If pcata_strategy() encounters an exception, or card_removal
1865 	 * is called, before this is complete, it is possible that
1866 	 * biodone will be called but the buffer (bp) wont
1867 	 * be released unless B_ASYNC flag is set. So
1868 	 * don't set B_ASYNC flag unless you mean it.
1869 	 */
1870 	(void) pcata_strategy(bp);
1871 	if (bp->b_error)
1872 		return (bp->b_error);
1873 
1874 	for (;;) {
1875 		if (!CARD_PRESENT_VALID(softp))
1876 			return (ENODEV);
1877 		if (bp->b_flags & B_DONE) {
1878 			if (bp->b_flags & B_ERROR)
1879 				return (bp->b_error);
1880 			else
1881 				return (0);
1882 		}
1883 		drv_usecwait(1000);
1884 	}
1885 }
1886 
1887 /* ddi print */
1888 static int
pcata_print(dev_t dev,char * str)1889 pcata_print(dev_t dev, char *str)
1890 {
1891 	void	*instance;
1892 	ata_soft_t *softp;
1893 
1894 
1895 	/* get instance number */
1896 	if (pcata_getinfo(NULL, DDI_INFO_DEVT2INSTANCE, (void *)dev,
1897 	    &instance) != DDI_SUCCESS) {
1898 		cmn_err(CE_CONT, "_print: pcata_getinfo"
1899 		    "return ENODEV\n");
1900 		return (ENODEV);
1901 	}
1902 
1903 	if (!(softp = ddi_get_soft_state(pcata_soft,
1904 	    (int)(uintptr_t)instance))) {
1905 		return (ENXIO);
1906 	}
1907 
1908 	cmn_err(CE_NOTE, "_print: socket %d %s", softp->sn, str);
1909 	return (0);
1910 
1911 }
1912 
1913 static int
pcata_rdrw(dev_t dev,struct uio * uio,int flag)1914 pcata_rdrw(dev_t dev, struct uio *uio, int flag)
1915 {
1916 	return (physio(pcata_strategy, (buf_t *)0, dev, flag, pcata_min, uio));
1917 }
1918 
1919 
1920 
1921 /* ARGSUSED2 */
1922 static int
pcata_read(dev_t dev,struct uio * uio,cred_t * cred_p)1923 pcata_read(dev_t dev, struct uio *uio, cred_t *cred_p)
1924 {
1925 	return (pcata_rdrw(dev, uio, B_READ));
1926 }
1927 
1928 
1929 
1930 /* ARGSUSED2 */
1931 static int
pcata_write(dev_t dev,struct uio * uio,cred_t * cred_p)1932 pcata_write(dev_t dev, struct uio *uio, cred_t *cred_p)
1933 {
1934 	return (pcata_rdrw(dev, uio, B_WRITE));
1935 }
1936 
1937 
1938 void
pcata_min(buf_t * bp)1939 pcata_min(buf_t *bp)
1940 {
1941 	ata_soft_t *softp;
1942 	void *instance;
1943 
1944 	if (pcata_getinfo(NULL, DDI_INFO_DEVT2INSTANCE, (void *)bp->b_edev,
1945 	    &instance) != DDI_SUCCESS)
1946 		cmn_err(CE_CONT, "Error in pcata_min\n");
1947 
1948 	softp = ddi_get_soft_state(pcata_soft, (int)(uintptr_t)instance);
1949 
1950 	if ((ROUNDUP(bp->b_bcount, NBPSCTR) >> SCTRSHFT) >
1951 	    softp->ab_max_transfer)
1952 
1953 		bp->b_bcount = softp->ab_max_transfer << SCTRSHFT;
1954 }
1955 
1956 static void
pcata_iosetup(ata_unit_t * unitp,struct ata_cmpkt * pktp)1957 pcata_iosetup(ata_unit_t *unitp, struct ata_cmpkt *pktp)
1958 {
1959 	uint32_t	sec_count;
1960 
1961 #ifdef ATA_DEBUG
1962 	if (pcata_debug & DENT) {
1963 		cmn_err(CE_CONT, "_iosetup (%p, %p)\n",
1964 		    (void *)unitp, (void *)pktp);
1965 	}
1966 #endif
1967 
1968 	/* check for error retry */
1969 	if (pktp->ac_flags & CFLAG_ERROR) {
1970 		pktp->ac_bytes_per_block = NBPSCTR;
1971 		sec_count = 1;
1972 	} else {
1973 		/*
1974 		 * Limit requetst to ab_max_transfer sectors.
1975 		 * The value is specified by the user in the
1976 		 * max_transfer property. It must be in the range 1 to 256.
1977 		 * When max_transfer is 0x100 it is bigger than 8 bits.
1978 		 * The spec says 0 represents 256 so it should be OK.
1979 		 */
1980 		sec_count = min((pktp->cp_bytexfer >> SCTRSHFT),
1981 		    unitp->a_blkp->ab_max_transfer);
1982 	}
1983 	pktp->ac_v_addr = pktp->ac_start_v_addr;
1984 	pktp->cp_resid = pktp->cp_bytexfer;
1985 	pktp->cp_bytexfer = sec_count << SCTRSHFT;
1986 
1987 #ifdef ATA_DEBUG
1988 	if (pcata_debug & DIO) {
1989 		cmn_err(CE_CONT,
1990 		    "_iosetup: asking for start 0x%lx count 0x%x\n",
1991 		    pktp->cp_srtsec, pktp->cp_bytexfer >> SCTRSHFT);
1992 	}
1993 #endif
1994 	/*
1995 	 * setup the task file registers
1996 	 */
1997 
1998 	if (pktp->cp_passthru) {
1999 		switch (((struct dadkio_rwcmd *)(pktp->cp_passthru))->cmd) {
2000 		case DADKIO_RWCMD_READ:
2001 			pktp->ac_cmd = unitp->au_rd_cmd;
2002 			pktp->ac_direction = AT_IN;
2003 			break;
2004 		case DADKIO_RWCMD_WRITE:
2005 			pktp->ac_cmd = unitp->au_wr_cmd;
2006 			pktp->ac_direction = AT_OUT;
2007 			break;
2008 		}
2009 	} else {
2010 		switch (pktp->ac_cdb) {
2011 		case DCMD_READ:
2012 		case DCMD_WRITE:
2013 		case DCMD_RECAL:
2014 		case DCMD_SEEK:
2015 		case DCMD_RDVER:
2016 			switch (pktp->ac_cdb) {
2017 			case DCMD_READ:
2018 				pktp->ac_cmd = unitp->au_rd_cmd;
2019 				pktp->ac_direction = AT_IN;
2020 				break;
2021 			case DCMD_WRITE:
2022 				pktp->ac_cmd = unitp->au_wr_cmd;
2023 				pktp->ac_direction = AT_OUT;
2024 				break;
2025 			case DCMD_RECAL:
2026 				pktp->ac_cmd = ATC_RECAL;
2027 				pktp->ac_direction = AT_NO_DATA;
2028 				break;
2029 			case DCMD_SEEK:
2030 				pktp->ac_cmd = ATC_SEEK;
2031 				pktp->ac_direction = AT_NO_DATA;
2032 				break;
2033 			case DCMD_RDVER:
2034 				pktp->ac_cmd = ATC_RDVER;
2035 				pktp->ac_direction = AT_NO_DATA;
2036 				break;
2037 			}
2038 			break;
2039 		default:
2040 			cmn_err(CE_CONT, "_iosetup: "
2041 			    "unrecognized cmd 0x%x\n",
2042 			    pktp->ac_cdb);
2043 			break;
2044 		}
2045 	}
2046 }
2047 
2048 
2049 /* ARGSUSED */
2050 int
pcata_spinup(ata_soft_t * softp,int slot)2051 pcata_spinup(ata_soft_t *softp, int slot)
2052 {
2053 
2054 	if (!(CARD_PRESENT_VALID(softp)))
2055 		return (DDI_FAILURE);
2056 
2057 	if (pcata_wait(AT_ALTSTATUS, ATS_DRDY, ATS_BSY, softp))
2058 		return (DDI_FAILURE);
2059 
2060 	pcata_wait_complete(softp);
2061 
2062 	/* spin up the drive */
2063 	PCIDE_OUTB(softp->handle, AT_DRVHD, ATDH_DRIVE0);
2064 
2065 	mutex_enter(&softp->hi_mutex);
2066 	softp->intr_pending++;
2067 	csx_Put8(softp->handle, AT_CMD, ATC_IDLE_IMMED);
2068 	mutex_exit(&softp->hi_mutex);
2069 
2070 	if (pcata_wait(AT_ALTSTATUS,
2071 	    (ATS_DRDY | ATS_DSC), (ATS_BSY | ATS_ERR), softp)) {
2072 #ifdef	ATA_DEBUG
2073 		cmn_err(CE_NOTE, "TIMEOUT SPINNING UP: ");
2074 		pcata_print_sttflag(csx_Get8(softp->handle, AT_ALTSTATUS));
2075 #endif
2076 		return (DDI_FAILURE);
2077 	}
2078 
2079 	pcata_wait_complete(softp);
2080 
2081 	/* set the R/W multiple value decided at first init  time */
2082 
2083 	PCIDE_OUTB(softp->handle, AT_COUNT, softp->ab_block_factor[0]);
2084 
2085 	mutex_enter(&softp->hi_mutex);
2086 	softp->intr_pending++;
2087 	csx_Put8(softp->handle, AT_CMD, ATC_SETMULT);
2088 	mutex_exit(&softp->hi_mutex);
2089 
2090 	if (pcata_wait(AT_STATUS, 0, ATS_BSY, softp)) {
2091 		/*
2092 		 * there should have been a drive here but it
2093 		 * didn't respond properly. It stayed BUSY.
2094 		 */
2095 #ifdef	ATA_DEBUG
2096 		cmn_err(CE_NOTE, "Error Spinning up ATA drive (after CPR)\n");
2097 #endif
2098 		return (DDI_FAILURE);
2099 	}
2100 
2101 	return (DDI_SUCCESS);
2102 }
2103 
2104 #ifdef  ATA_DEBUG
2105 static char	*
2106 ata_sttvals[] = { "err", "idx", "corr", "drq", "dsc", "dwf", "drdy", "bsy" };
2107 
2108 
2109 static void
pcata_print_sttflag(int svalue)2110 pcata_print_sttflag(int svalue)
2111 {
2112 	int	i;
2113 	char	buf[80];
2114 
2115 	(void) sprintf(buf, "_sttflag = 0x%x [ ", svalue);
2116 
2117 	for (i = 7; i >= 0; i--,  svalue <<= 1) {
2118 		if (svalue & 0x80) {
2119 			(void) strcat(buf, ata_sttvals[i]);
2120 			(void) strcat(buf, " ");
2121 		}
2122 	}
2123 	cmn_err(CE_CONT, "%s ]\n", buf);
2124 }
2125 #endif
2126