Deleted Added
full compact
twe_freebsd.c (117126) twe_freebsd.c (118508)
1/*-
2 * Copyright (c) 2000 Michael Smith
3 * Copyright (c) 2000 BSDi
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 10 unchanged lines hidden (view full) ---

19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
1/*-
2 * Copyright (c) 2000 Michael Smith
3 * Copyright (c) 2000 BSDi
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 10 unchanged lines hidden (view full) ---

19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD: head/sys/dev/twe/twe_freebsd.c 117126 2003-07-01 15:52:06Z scottl $
27 * $FreeBSD: head/sys/dev/twe/twe_freebsd.c 118508 2003-08-05 19:55:21Z ps $
28 */
29
30/*
31 * FreeBSD-specific code.
32 */
33
34#include <sys/param.h>
35#include <sys/cons.h>

--- 83 unchanged lines hidden (view full) ---

119 PCI device interface
120 ********************************************************************************
121 ********************************************************************************/
122
123static int twe_probe(device_t dev);
124static int twe_attach(device_t dev);
125static void twe_free(struct twe_softc *sc);
126static int twe_detach(device_t dev);
28 */
29
30/*
31 * FreeBSD-specific code.
32 */
33
34#include <sys/param.h>
35#include <sys/cons.h>

--- 83 unchanged lines hidden (view full) ---

119 PCI device interface
120 ********************************************************************************
121 ********************************************************************************/
122
123static int twe_probe(device_t dev);
124static int twe_attach(device_t dev);
125static void twe_free(struct twe_softc *sc);
126static int twe_detach(device_t dev);
127static int twe_shutdown(device_t dev);
127static void twe_shutdown(device_t dev);
128static int twe_suspend(device_t dev);
129static int twe_resume(device_t dev);
130static void twe_pci_intr(void *arg);
131static void twe_intrhook(void *arg);
132
133static device_method_t twe_methods[] = {
134 /* Device interface */
135 DEVMETHOD(device_probe, twe_probe),

--- 55 unchanged lines hidden (view full) ---

191 debug_called(4);
192
193 /*
194 * Initialise the softc structure.
195 */
196 sc = device_get_softc(dev);
197 sc->twe_dev = dev;
198
128static int twe_suspend(device_t dev);
129static int twe_resume(device_t dev);
130static void twe_pci_intr(void *arg);
131static void twe_intrhook(void *arg);
132
133static device_method_t twe_methods[] = {
134 /* Device interface */
135 DEVMETHOD(device_probe, twe_probe),

--- 55 unchanged lines hidden (view full) ---

191 debug_called(4);
192
193 /*
194 * Initialise the softc structure.
195 */
196 sc = device_get_softc(dev);
197 sc->twe_dev = dev;
198
199 sysctl_ctx_init(&sc->sysctl_ctx);
200 sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx,
201 SYSCTL_STATIC_CHILDREN(_hw), OID_AUTO,
202 device_get_nameunit(dev), CTLFLAG_RD, 0, "");
203 if (sc->sysctl_tree == NULL) {
204 twe_printf(sc, "cannot add sysctl tree node\n");
205 return (ENXIO);
206 }
207 SYSCTL_ADD_STRING(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
208 OID_AUTO, "driver_version", CTLFLAG_RD, "$Revision$", 0,
209 "TWE driver version");
210
199 /*
200 * Make sure we are going to be able to talk to this board.
201 */
202 command = pci_read_config(dev, PCIR_COMMAND, 2);
203 if ((command & PCIM_CMD_PORTEN) == 0) {
204 twe_printf(sc, "register window not available\n");
205 return(ENXIO);
206 }

--- 134 unchanged lines hidden (view full) ---

341
342 /* release the register window mapping */
343 if (sc->twe_io != NULL)
344 bus_release_resource(sc->twe_dev, SYS_RES_IOPORT, TWE_IO_CONFIG_REG, sc->twe_io);
345
346 /* destroy control device */
347 if (sc->twe_dev_t != (dev_t)NULL)
348 destroy_dev(sc->twe_dev_t);
211 /*
212 * Make sure we are going to be able to talk to this board.
213 */
214 command = pci_read_config(dev, PCIR_COMMAND, 2);
215 if ((command & PCIM_CMD_PORTEN) == 0) {
216 twe_printf(sc, "register window not available\n");
217 return(ENXIO);
218 }

--- 134 unchanged lines hidden (view full) ---

353
354 /* release the register window mapping */
355 if (sc->twe_io != NULL)
356 bus_release_resource(sc->twe_dev, SYS_RES_IOPORT, TWE_IO_CONFIG_REG, sc->twe_io);
357
358 /* destroy control device */
359 if (sc->twe_dev_t != (dev_t)NULL)
360 destroy_dev(sc->twe_dev_t);
361
362 sysctl_ctx_free(&sc->sysctl_ctx);
349}
350
351/********************************************************************************
352 * Disconnect from the controller completely, in preparation for unload.
353 */
354static int
355twe_detach(device_t dev)
356{

--- 5 unchanged lines hidden (view full) ---

362 error = EBUSY;
363 s = splbio();
364 if (sc->twe_state & TWE_STATE_OPEN)
365 goto out;
366
367 /*
368 * Shut the controller down.
369 */
363}
364
365/********************************************************************************
366 * Disconnect from the controller completely, in preparation for unload.
367 */
368static int
369twe_detach(device_t dev)
370{

--- 5 unchanged lines hidden (view full) ---

376 error = EBUSY;
377 s = splbio();
378 if (sc->twe_state & TWE_STATE_OPEN)
379 goto out;
380
381 /*
382 * Shut the controller down.
383 */
370 if ((error = twe_shutdown(dev)))
371 goto out;
384 twe_shutdown(dev);
372
373 twe_free(sc);
374
375 error = 0;
376 out:
377 splx(s);
378 return(error);
379}
380
381/********************************************************************************
382 * Bring the controller down to a dormant state and detach all child devices.
383 *
384 * Note that we can assume that the bioq on the controller is empty, as we won't
385 * allow shutdown if any device is open.
386 */
385
386 twe_free(sc);
387
388 error = 0;
389 out:
390 splx(s);
391 return(error);
392}
393
394/********************************************************************************
395 * Bring the controller down to a dormant state and detach all child devices.
396 *
397 * Note that we can assume that the bioq on the controller is empty, as we won't
398 * allow shutdown if any device is open.
399 */
387static int
400static void
388twe_shutdown(device_t dev)
389{
390 struct twe_softc *sc = device_get_softc(dev);
401twe_shutdown(device_t dev)
402{
403 struct twe_softc *sc = device_get_softc(dev);
391 int i, s, error;
404 int i, s;
392
393 debug_called(4);
394
395 s = splbio();
405
406 debug_called(4);
407
408 s = splbio();
396 error = 0;
397
398 /*
399 * Delete all our child devices.
400 */
401 for (i = 0; i < TWE_MAX_UNITS; i++) {
409
410 /*
411 * Delete all our child devices.
412 */
413 for (i = 0; i < TWE_MAX_UNITS; i++) {
402 if (sc->twe_drive[i].td_disk != 0) {
403 if ((error = device_delete_child(sc->twe_dev, sc->twe_drive[i].td_disk)) != 0)
404 goto out;
405 sc->twe_drive[i].td_disk = 0;
406 }
414 twe_detach_drive(sc, i);
407 }
408
409 /*
410 * Bring the controller down.
411 */
412 twe_deinit(sc);
413
415 }
416
417 /*
418 * Bring the controller down.
419 */
420 twe_deinit(sc);
421
414 out:
415 splx(s);
422 splx(s);
416 return(error);
417}
418
419/********************************************************************************
420 * Bring the controller to a quiescent state, ready for system suspend.
421 */
422static int
423twe_suspend(device_t dev)
424{

--- 50 unchanged lines hidden (view full) ---

475
476 /* call core startup routine */
477 twe_init(sc);
478}
479
480/********************************************************************************
481 * Given a detected drive, attach it to the bio interface.
482 *
423}
424
425/********************************************************************************
426 * Bring the controller to a quiescent state, ready for system suspend.
427 */
428static int
429twe_suspend(device_t dev)
430{

--- 50 unchanged lines hidden (view full) ---

481
482 /* call core startup routine */
483 twe_init(sc);
484}
485
486/********************************************************************************
487 * Given a detected drive, attach it to the bio interface.
488 *
483 * This is called from twe_init.
489 * This is called from twe_add_unit.
484 */
485void
486twe_attach_drive(struct twe_softc *sc, struct twe_drive *dr)
487{
488 char buf[80];
489 int error;
490
491 dr->td_disk = device_add_child(sc->twe_dev, NULL, -1);
492 if (dr->td_disk == NULL) {
493 twe_printf(sc, "device_add_child failed\n");
494 return;
495 }
496 device_set_ivars(dr->td_disk, dr);
497
498 /*
499 * XXX It would make sense to test the online/initialising bits, but they seem to be
500 * always set...
501 */
490 */
491void
492twe_attach_drive(struct twe_softc *sc, struct twe_drive *dr)
493{
494 char buf[80];
495 int error;
496
497 dr->td_disk = device_add_child(sc->twe_dev, NULL, -1);
498 if (dr->td_disk == NULL) {
499 twe_printf(sc, "device_add_child failed\n");
500 return;
501 }
502 device_set_ivars(dr->td_disk, dr);
503
504 /*
505 * XXX It would make sense to test the online/initialising bits, but they seem to be
506 * always set...
507 */
502 sprintf(buf, "%s, %s", twe_describe_code(twe_table_unittype, dr->td_type),
508 sprintf(buf, "Unit %d, %s, %s",
509 dr->td_unit,
510 twe_describe_code(twe_table_unittype, dr->td_type),
503 twe_describe_code(twe_table_unitstate, dr->td_state & TWE_PARAM_UNITSTATUS_MASK));
504 device_set_desc_copy(dr->td_disk, buf);
505
506 if ((error = bus_generic_attach(sc->twe_dev)) != 0)
507 twe_printf(sc, "bus_generic_attach returned %d\n", error);
508}
509
510/********************************************************************************
511 twe_describe_code(twe_table_unitstate, dr->td_state & TWE_PARAM_UNITSTATUS_MASK));
512 device_set_desc_copy(dr->td_disk, buf);
513
514 if ((error = bus_generic_attach(sc->twe_dev)) != 0)
515 twe_printf(sc, "bus_generic_attach returned %d\n", error);
516}
517
518/********************************************************************************
519 * Detach the specified unit if it exsists
520 *
521 * This is called from twe_del_unit.
522 */
523void
524twe_detach_drive(struct twe_softc *sc, int unit)
525{
526
527 if (sc->twe_drive[unit].td_disk != 0) {
528 if (device_delete_child(sc->twe_dev, sc->twe_drive[unit].td_disk) != 0)
529 twe_printf(sc, "failed to delete unit %d\n", unit);
530 sc->twe_drive[unit].td_disk = 0;
531 }
532}
533
534/********************************************************************************
511 * Clear a PCI parity error.
512 */
513void
514twe_clear_pci_parity_error(struct twe_softc *sc)
515{
516 TWE_CONTROL(sc, TWE_CONTROL_CLEAR_PARITY_ERROR);
517 pci_write_config(sc->twe_dev, PCIR_STATUS, TWE_PCI_CLEAR_PARITY_ERROR, 2);
518}

--- 289 unchanged lines hidden (view full) ---

808 * Map/unmap (tr)'s command and data in the controller's addressable space.
809 *
810 * These routines ensure that the data which the controller is going to try to
811 * access is actually visible to the controller, in a machine-independant
812 * fashion. Due to a hardware limitation, I/O buffers must be 512-byte aligned
813 * and we take care of that here as well.
814 */
815static void
535 * Clear a PCI parity error.
536 */
537void
538twe_clear_pci_parity_error(struct twe_softc *sc)
539{
540 TWE_CONTROL(sc, TWE_CONTROL_CLEAR_PARITY_ERROR);
541 pci_write_config(sc->twe_dev, PCIR_STATUS, TWE_PCI_CLEAR_PARITY_ERROR, 2);
542}

--- 289 unchanged lines hidden (view full) ---

832 * Map/unmap (tr)'s command and data in the controller's addressable space.
833 *
834 * These routines ensure that the data which the controller is going to try to
835 * access is actually visible to the controller, in a machine-independant
836 * fashion. Due to a hardware limitation, I/O buffers must be 512-byte aligned
837 * and we take care of that here as well.
838 */
839static void
840twe_fillin_sgl(TWE_SG_Entry *sgl, bus_dma_segment_t *segs, int nsegments, int max_sgl)
841{
842 int i;
843
844 for (i = 0; i < nsegments; i++) {
845 sgl[i].address = segs[i].ds_addr;
846 sgl[i].length = segs[i].ds_len;
847 }
848 for (; i < max_sgl; i++) { /* XXX necessary? */
849 sgl[i].address = 0;
850 sgl[i].length = 0;
851 }
852}
853
854static void
816twe_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
817{
818 struct twe_request *tr = (struct twe_request *)arg;
819 TWE_Command *cmd = &tr->tr_command;
855twe_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
856{
857 struct twe_request *tr = (struct twe_request *)arg;
858 TWE_Command *cmd = &tr->tr_command;
820 int i;
821
822 debug_called(4);
823
824 /* save base of first segment in command (applicable if there only one segment) */
825 tr->tr_dataphys = segs[0].ds_addr;
826
827 /* correct command size for s/g list size */
828 tr->tr_command.generic.size += 2 * nsegments;
829
830 /*
831 * Due to the fact that parameter and I/O commands have the scatter/gather list in
832 * different places, we need to determine which sort of command this actually is
833 * before we can populate it correctly.
834 */
835 switch(cmd->generic.opcode) {
836 case TWE_OP_GET_PARAM:
837 case TWE_OP_SET_PARAM:
838 cmd->generic.sgl_offset = 2;
859
860 debug_called(4);
861
862 /* save base of first segment in command (applicable if there only one segment) */
863 tr->tr_dataphys = segs[0].ds_addr;
864
865 /* correct command size for s/g list size */
866 tr->tr_command.generic.size += 2 * nsegments;
867
868 /*
869 * Due to the fact that parameter and I/O commands have the scatter/gather list in
870 * different places, we need to determine which sort of command this actually is
871 * before we can populate it correctly.
872 */
873 switch(cmd->generic.opcode) {
874 case TWE_OP_GET_PARAM:
875 case TWE_OP_SET_PARAM:
876 cmd->generic.sgl_offset = 2;
839 for (i = 0; i < nsegments; i++) {
840 cmd->param.sgl[i].address = segs[i].ds_addr;
841 cmd->param.sgl[i].length = segs[i].ds_len;
842 }
843 for (; i < TWE_MAX_SGL_LENGTH; i++) { /* XXX necessary? */
844 cmd->param.sgl[i].address = 0;
845 cmd->param.sgl[i].length = 0;
846 }
877 twe_fillin_sgl(&cmd->param.sgl[0], segs, nsegments, TWE_MAX_SGL_LENGTH);
847 break;
848 case TWE_OP_READ:
849 case TWE_OP_WRITE:
850 cmd->generic.sgl_offset = 3;
878 break;
879 case TWE_OP_READ:
880 case TWE_OP_WRITE:
881 cmd->generic.sgl_offset = 3;
851 for (i = 0; i < nsegments; i++) {
852 cmd->io.sgl[i].address = segs[i].ds_addr;
853 cmd->io.sgl[i].length = segs[i].ds_len;
854 }
855 for (; i < TWE_MAX_SGL_LENGTH; i++) { /* XXX necessary? */
856 cmd->io.sgl[i].address = 0;
857 cmd->io.sgl[i].length = 0;
858 }
882 twe_fillin_sgl(&cmd->io.sgl[0], segs, nsegments, TWE_MAX_SGL_LENGTH);
859 break;
883 break;
860 default:
861 /* no s/g list, nothing to do */
884 case TWE_OP_ATA_PASSTHROUGH:
885 cmd->generic.sgl_offset = 5;
886 twe_fillin_sgl(&cmd->ata.sgl[0], segs, nsegments, TWE_MAX_ATA_SGL_LENGTH);
862 break;
887 break;
888 default:
889 /*
890 * Fall back to what the linux driver does.
891 * Do this because the API may send an opcode
892 * the driver knows nothing about and this will
893 * at least stop PCIABRT's from hosing us.
894 */
895 switch (cmd->generic.sgl_offset) {
896 case 2:
897 twe_fillin_sgl(&cmd->param.sgl[0], segs, nsegments, TWE_MAX_SGL_LENGTH);
898 break;
899 case 3:
900 twe_fillin_sgl(&cmd->io.sgl[0], segs, nsegments, TWE_MAX_SGL_LENGTH);
901 break;
902 case 5:
903 twe_fillin_sgl(&cmd->ata.sgl[0], segs, nsegments, TWE_MAX_ATA_SGL_LENGTH);
904 break;
905 }
863 }
864}
865
866static void
867twe_setup_request_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
868{
869 struct twe_request *tr = (struct twe_request *)arg;
870

--- 105 unchanged lines hidden ---
906 }
907}
908
909static void
910twe_setup_request_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
911{
912 struct twe_request *tr = (struct twe_request *)arg;
913

--- 105 unchanged lines hidden ---