Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Mar 2005 00:24:30 -0500
From:      David Sze <dsze@alumni.uwaterloo.ca>
To:        freebsd-stable@freebsd.org
Subject:   Re: Can FreeBSD be installed on DellPowerEdge2800 ?
Message-ID:  <6.2.1.2.2.20050310000250.05746d80@mail.distrust.net>
In-Reply-To: <6.2.1.2.2.20050308215231.0537dff0@mail.distrust.net>
References:  <BA84A761ED41C54893BED691A4A574CF977226@EXCH5.eurowings.com> <4224F19C.2090207@rackspace.com> <6.2.1.2.2.20050301234017.03e93e68@pop3.tellurian.com> <4225CCE4.3080304@rackspace.com> <20050308235853.GA81150@mail.distrust.net> <422E4986.6080409@samsco.org> <6.2.1.2.2.20050308215231.0537dff0@mail.distrust.net>

next in thread | previous in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
At 09:15 PM 08/03/2005 -0600, David Sze wrote this to All:
>At 05:55 PM 08/03/2005 -0700, Scott Long wrote this to All:
> >>David Sze wrote:
> >>On my 2850 the upper 1GB of RAM cannot be addressed without PAE support
> >>in the kernel.  However, amr in 4.11-RELEASE does indeed seem to have
> >>trouble with PAE.  The result being that with the option in the kernel,
> >>the root device (ufs:/dev/amrd0s1a) cannot be found.
> >>
> >>I backported scottl's amr PAE fixes from RELENG_5; the diffs applied
> >>cleanly (with offsets).  I'm happy to report that my 2850 can now
> >>address its full 4GB and see its amr volumes.
> >>
> >>The diff against 4.11-RELEASE is attached, hopefully someone will be
> >>willing to commit it to RELENG_4.
> >
> >I don't have the cycles to watch after RELENG_4, so I'll have to take
> >your word that this works.  What date is this patch against?  I
> >committed some follow-up fixes last week that are required for
> >management apps to work (and yes, LSI is getting ready to support
> >FreeBSD with management apps).
>
>The patch is against 4.11-RELEASE, and is just a backport of your commit
>from Dec. 5th
>(http://lists.freebsd.org/pipermail/cvs-all/2004-December/094923.html).
>There haven't been any changes to amr since release, so it should apply
>directly to RELENG_4 as well.
>
>I left out the subsequent ioctl fixes and LSI 320-2E support.  They look
>straightforward, but I don't have the software or hardware to test them.
>If you'd like them in there before committing to RELENG_4, I can take a
>stab at it and post a new patch.

A new patch is attached to this message that synchronizes the RELENG_4 amr 
driver with CURRENT, minus the SMPng locking and amd64/ia64 ioctl 
compatibility stuff.  The fixes and their corresponding file revisions are:

Greater than 4GB support
         amr.c           1.55, 1.56, 1.59
         amr_cam.c       1.10
         amr_pci.c       1.24
         amrvar.h        1.23

ioctl fixes for LSI management tools
         amr.c           1.60, 1.61

Fix module unloading
         amr_cam.c       1.12
         amrvar.h        1.24

Check for NULL amrd_sc in amrd_dump
         amr_disk.c      1.32

Support for LSI 320-2E PCI Express controller
         amr_pci.c       1.27
         amrreg.h        1.8
         amrvar.h        1.26

The only part of the patch I've tested is the >4GB support.  The rest 
compiles but I can't vouch for its validity because I don't have the 
software or hardware to test.


[-- Attachment #2 --]
*** sys/dev/amr/amr.c.orig	Thu Jul 22 09:35:18 2004
--- sys/dev/amr/amr.c	Wed Mar  9 08:36:28 2005
***************
*** 1,6 ****
--- 1,7 ----
  /*-
   * Copyright (c) 1999,2000 Michael Smith
   * Copyright (c) 2000 BSDi
+  * Copyright (c) 2005 Scott Long
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
***************
*** 25,31 ****
   * SUCH DAMAGE.
   *
   * Copyright (c) 2002 Eric Moore
!  * Copyright (c) 2002 LSI Logic Corporation
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
--- 26,32 ----
   * SUCH DAMAGE.
   *
   * Copyright (c) 2002 Eric Moore
!  * Copyright (c) 2002, 2004 LSI Logic Corporation
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
***************
*** 132,143 ****
   * Command processing.
   */
  static int	amr_bio_command(struct amr_softc *sc, struct amr_command **acp);
! static int	amr_wait_command(struct amr_command *ac);
  static int	amr_getslot(struct amr_command *ac);
! static void	amr_mapcmd(struct amr_command *ac);
  static void	amr_unmapcmd(struct amr_command *ac);
  static int	amr_start(struct amr_command *ac);
  static void	amr_complete(void *context, int pending);
  
  /*
   * Status monitoring
--- 133,147 ----
   * Command processing.
   */
  static int	amr_bio_command(struct amr_softc *sc, struct amr_command **acp);
! static int	amr_wait_command(struct amr_command *ac) __unused;
  static int	amr_getslot(struct amr_command *ac);
! static int	amr_mapcmd(struct amr_command *ac);
  static void	amr_unmapcmd(struct amr_command *ac);
  static int	amr_start(struct amr_command *ac);
+ static int	amr_start1(struct amr_softc *sc, struct amr_command *ac);
  static void	amr_complete(void *context, int pending);
+ static void	amr_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
+ static void	amr_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
  
  /*
   * Status monitoring
***************
*** 150,155 ****
--- 154,160 ----
  static int	amr_quartz_submit_command(struct amr_softc *sc);
  static int	amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave);
  static int	amr_quartz_poll_command(struct amr_command *ac);
+ static int	amr_quartz_poll_command1(struct amr_softc *sc, struct amr_command *ac);
  
  static int	amr_std_submit_command(struct amr_softc *sc);
  static int	amr_std_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave);
***************
*** 217,222 ****
--- 222,228 ----
  	sc->amr_submit_command = amr_quartz_submit_command;
  	sc->amr_get_work       = amr_quartz_get_work;
  	sc->amr_poll_command   = amr_quartz_poll_command;
+ 	sc->amr_poll_command1  = amr_quartz_poll_command1;
      } else {
  	sc->amr_submit_command = amr_std_submit_command;
  	sc->amr_get_work       = amr_std_get_work;
***************
*** 430,437 ****
  
      case AMR_IO_COMMAND:
  	debug(1, "AMR_IO_COMMAND  0x%x", au->au_cmd[0]);
  	/* handle inbound data buffer */
! 	if (au->au_length != 0) {
  	    if ((dp = malloc(au->au_length, M_DEVBUF, M_WAITOK)) == NULL) {
  		error = ENOMEM;
  		break;
--- 436,447 ----
  
      case AMR_IO_COMMAND:
  	debug(1, "AMR_IO_COMMAND  0x%x", au->au_cmd[0]);
+ 	/* Logical Drive not supported by the driver */
+ 	if (au->au_cmd[0] == 0xa4 && au->au_cmd[1] == 0x1c)
+ 	    return (ENOIOCTL);
+ 
  	/* handle inbound data buffer */
! 	if (au->au_length != 0 && au->au_cmd[0] != 0x06) {
  	    if ((dp = malloc(au->au_length, M_DEVBUF, M_WAITOK)) == NULL) {
  		error = ENOMEM;
  		break;
***************
*** 681,690 ****
      if ((ac = amr_alloccmd(sc)) == NULL)
  	goto out;
      /* allocate the response structure */
!     if ((result = malloc(bufsize, M_DEVBUF, M_NOWAIT)) == NULL)
  	goto out;
      /* set command flags */
!     ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
      
      /* point the command at our data */
      ac->ac_data = result;
--- 691,701 ----
      if ((ac = amr_alloccmd(sc)) == NULL)
  	goto out;
      /* allocate the response structure */
!     if ((result = malloc(bufsize, M_DEVBUF, M_ZERO|M_NOWAIT)) == NULL)
  	goto out;
      /* set command flags */
! 
!     ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAIN;
      
      /* point the command at our data */
      ac->ac_data = result;
***************
*** 794,799 ****
--- 805,814 ----
      /* spin until something prevents us from doing any work */
      for (;;) {
  
+ 	/* Don't bother to queue commands no bounce buffers are available. */
+ 	if (sc->amr_state & AMR_STATE_QUEUE_FRZN)
+ 	    break;
+ 
  	/* try to get a ready command */
  	ac = amr_dequeue_ready(sc);
  
***************
*** 967,972 ****
--- 982,998 ----
      return(error);
  }
  
+ static void
+ amr_setup_polled_dmamap(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
+ {
+     struct amr_command *ac = arg;
+     struct amr_softc *sc = ac->ac_sc;
+ 
+     amr_setup_dmamap(arg, segs, nsegs, err);
+     bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREREAD);
+     sc->amr_poll_command1(sc, ac);
+ }
+ 
  /********************************************************************************
   * Take a command, submit it to the controller and busy-wait for it to return.
   * Returns nonzero on error.  Can be safely called with interrupts enabled.
***************
*** 975,991 ****
  amr_quartz_poll_command(struct amr_command *ac)
  {
      struct amr_softc	*sc = ac->ac_sc;
!     int			s;
!     int			error,count;
  
      debug_called(2);
  
      /* now we have a slot, we can map the command (unmapped in amr_complete) */
!     amr_mapcmd(ac);
  
!     s = splbio();
  
!     if ((sc->amr_state & AMR_STATE_CRASHDUMP) == 0) {
  	count=0;
  	while (sc->amr_busyslots){
  	    tsleep(sc, PRIBIO | PCATCH, "amrpoll", hz);
--- 1001,1033 ----
  amr_quartz_poll_command(struct amr_command *ac)
  {
      struct amr_softc	*sc = ac->ac_sc;
!     int			s, error;
  
      debug_called(2);
  
+     s = splbio();
+     error = 0;
+ 
      /* now we have a slot, we can map the command (unmapped in amr_complete) */
!     if (ac->ac_data != 0) {
! 	if (bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_dmamap, ac->ac_data,
! 	    ac->ac_length, amr_setup_polled_dmamap, ac, BUS_DMA_NOWAIT) != 0) {
! 	    error = 1;
! 	}
!     } else {
! 	error = amr_quartz_poll_command1(sc, ac);
!     }
  
!     splx(s);
!     return (error);
! }
! 
! static int
! amr_quartz_poll_command1(struct amr_softc *sc, struct amr_command *ac)
! {
!     int count, error;
  
!     if ((sc->amr_state & AMR_STATE_INTEN) == 0) {
  	count=0;
  	while (sc->amr_busyslots){
  	    tsleep(sc, PRIBIO | PCATCH, "amrpoll", hz);
***************
*** 996,1003 ****
  
  	if(sc->amr_busyslots) {
  	    device_printf(sc->amr_dev, "adapter is busy\n");
! 	    splx(s);
! 	    amr_unmapcmd(ac);
      	    ac->ac_status=0;
  	    return(1);
          }
--- 1038,1045 ----
  
  	if(sc->amr_busyslots) {
  	    device_printf(sc->amr_dev, "adapter is busy\n");
! 	    if (ac->ac_data != NULL)
! 		bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
      	    ac->ac_status=0;
  	    return(1);
          }
***************
*** 1027,1036 ****
      AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_ACK);
      while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK);
  
-     splx(s);
- 
      /* unmap the command's data buffer */
!     amr_unmapcmd(ac);
  
      return(error);
  }
--- 1069,1077 ----
      AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_ACK);
      while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK);
  
      /* unmap the command's data buffer */
!     bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_POSTREAD);
!     bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
  
      return(error);
  }
***************
*** 1113,1124 ****
      } else {
          ac->ac_mailbox.mb_nsgelem = nsegments;
  	*sgc = nsegments;
! 	ac->ac_mailbox.mb_physaddr = sc->amr_sgbusaddr + (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
  	for (i = 0; i < nsegments; i++, sg++) {
  	    sg->sg_addr = segs[i].ds_addr;
  	    sg->sg_count = segs[i].ds_len;
  	}
      }
  }
  
  static void
--- 1154,1167 ----
      } else {
          ac->ac_mailbox.mb_nsgelem = nsegments;
  	*sgc = nsegments;
! 	ac->ac_mailbox.mb_physaddr = sc->amr_sgbusaddr +
! 	    (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
  	for (i = 0; i < nsegments; i++, sg++) {
  	    sg->sg_addr = segs[i].ds_addr;
  	    sg->sg_count = segs[i].ds_len;
  	}
      }
+ 
  }
  
  static void
***************
*** 1142,1157 ****
  	} else {
  	    /* save s/g table information in passthrough */
  	    aep->ap_no_sg_elements = nsegments;
! 	    aep->ap_data_transfer_address = sc->amr_sgbusaddr + (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
! 	    /* populate s/g table (overwrites previous call which mapped the passthrough) */
  	    for (i = 0; i < nsegments; i++, sg++) {
  		sg->sg_addr = segs[i].ds_addr;
  		sg->sg_count = segs[i].ds_len;
  		debug(3, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count);
  	    }
  	}
! 	debug(3, "slot %d  %d segments at 0x%x, passthrough at 0x%x", ac->ac_slot,
! 	    aep->ap_no_sg_elements, aep->ap_data_transfer_address, ac->ac_dataphys);
      } else {
  	if (nsegments < 2) {
  	    ap->ap_no_sg_elements = 0;
--- 1185,1205 ----
  	} else {
  	    /* save s/g table information in passthrough */
  	    aep->ap_no_sg_elements = nsegments;
! 	    aep->ap_data_transfer_address = sc->amr_sgbusaddr +
! 		(ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
! 	    /*
! 	     * populate s/g table (overwrites previous call which mapped the
! 	     * passthrough)
! 	     */
  	    for (i = 0; i < nsegments; i++, sg++) {
  		sg->sg_addr = segs[i].ds_addr;
  		sg->sg_count = segs[i].ds_len;
  		debug(3, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count);
  	    }
  	}
! 	debug(3, "slot %d  %d segments at 0x%x, passthrough at 0x%x\n",
! 	    ac->ac_slot, aep->ap_no_sg_elements, aep->ap_data_transfer_address,
! 	    ac->ac_dataphys);
      } else {
  	if (nsegments < 2) {
  	    ap->ap_no_sg_elements = 0;
***************
*** 1159,1178 ****
  	} else {
  	    /* save s/g table information in passthrough */
  	    ap->ap_no_sg_elements = nsegments;
! 	    ap->ap_data_transfer_address = sc->amr_sgbusaddr + (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
! 	    /* populate s/g table (overwrites previous call which mapped the passthrough) */
  	    for (i = 0; i < nsegments; i++, sg++) {
  		sg->sg_addr = segs[i].ds_addr;
  		sg->sg_count = segs[i].ds_len;
  		debug(3, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count);
  	    }
  	}
! 	debug(3, "slot %d  %d segments at 0x%x, passthrough at 0x%x", ac->ac_slot,
! 	    ap->ap_no_sg_elements, ap->ap_data_transfer_address, ac->ac_dataphys);
!     }
  }
  
! static void
  amr_mapcmd(struct amr_command *ac)
  {
      struct amr_softc	*sc = ac->ac_sc;
--- 1207,1248 ----
  	} else {
  	    /* save s/g table information in passthrough */
  	    ap->ap_no_sg_elements = nsegments;
! 	    ap->ap_data_transfer_address = sc->amr_sgbusaddr +
! 		(ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
! 	    /*
! 	     * populate s/g table (overwrites previous call which mapped the
! 	     * passthrough)
! 	     */
  	    for (i = 0; i < nsegments; i++, sg++) {
  		sg->sg_addr = segs[i].ds_addr;
  		sg->sg_count = segs[i].ds_len;
  		debug(3, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count);
  	    }
  	}
! 	debug(3, "slot %d  %d segments at 0x%x, passthrough at 0x%x",
! 	    ac->ac_slot, ap->ap_no_sg_elements, ap->ap_data_transfer_address,
! 	    ac->ac_dataphys);
!     }
!     if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
! 	bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap,
! 	    BUS_DMASYNC_PREREAD);
!     if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
! 	bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap,
! 	    BUS_DMASYNC_PREWRITE);
!     if ((ac->ac_flags & (AMR_CMD_CCB_DATAIN | AMR_CMD_CCB_DATAOUT)) == 0)
! 	panic("no direction for ccb?\n");
! 
!     if (ac->ac_flags & AMR_CMD_DATAIN)
! 	bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREREAD);
!     if (ac->ac_flags & AMR_CMD_DATAOUT)
! 	bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREWRITE);
! 
!     ac->ac_flags |= AMR_CMD_MAPPED;
! 
!     amr_start1(sc, ac);
  }
  
! static int
  amr_mapcmd(struct amr_command *ac)
  {
      struct amr_softc	*sc = ac->ac_sc;
***************
*** 1180,1207 ****
      debug_called(3);
  
      /* if the command involves data at all, and hasn't been mapped */
!     if (!(ac->ac_flags & AMR_CMD_MAPPED)) {
! 
! 	if (ac->ac_data != NULL) {
  	    /* map the data buffers into bus space and build the s/g list */
! 	    bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_dmamap, ac->ac_data, ac->ac_length,
! 			    amr_setup_dmamap, ac, 0);
! 	    if (ac->ac_flags & AMR_CMD_DATAIN)
! 		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_PREREAD);
! 	    if (ac->ac_flags & AMR_CMD_DATAOUT)
! 		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_PREWRITE);
! 	}
  
! 	if (ac->ac_ccb_data != NULL) {
! 	    bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, ac->ac_ccb_data, ac->ac_ccb_length,
! 			    amr_setup_ccbmap, ac, 0);
! 	    if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
! 		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_PREREAD);
! 	    if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
! 		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_PREWRITE);
! 	}
! 	ac->ac_flags |= AMR_CMD_MAPPED;
!     }
  }
  
  static void
--- 1250,1278 ----
      debug_called(3);
  
      /* if the command involves data at all, and hasn't been mapped */
!     if ((ac->ac_flags & AMR_CMD_MAPPED) == 0 && (ac->ac_data != NULL)) {
! 	if (ac->ac_ccb_data == NULL) {
  	    /* map the data buffers into bus space and build the s/g list */
! 	    if (bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_dmamap, ac->ac_data,
! 		ac->ac_length, amr_setup_data_dmamap, ac, 0) == EINPROGRESS) {
! 		sc->amr_state |= AMR_STATE_QUEUE_FRZN;
! 	    }
! 	} else {
! 	    if (bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_dmamap, ac->ac_data,
! 		ac->ac_length, amr_setup_dmamap, ac, BUS_DMA_NOWAIT) != 0){
! 		return (ENOMEM);
! 	    }
! 	    if (bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_ccb_dmamap,
! 		ac->ac_ccb_data, ac->ac_ccb_length, amr_setup_ccbmap, ac,
! 		0) == EINPROGRESS) {
! 		sc->amr_state |= AMR_STATE_QUEUE_FRZN;
! 	    }
!      }
!    } else if ((ac->ac_flags & AMR_CMD_MAPPED) == 0) {
!     	amr_start1(sc, ac);
!    }
  
!     return (0);
  }
  
  static void
***************
*** 1216,1238 ****
  
  	if (ac->ac_data != NULL) {
  	    if (ac->ac_flags & AMR_CMD_DATAIN)
! 		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_POSTREAD);
  	    if (ac->ac_flags & AMR_CMD_DATAOUT)
! 		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_POSTWRITE);
  	    bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
  	}
  
  	if (ac->ac_ccb_data != NULL) {
  	    if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
! 		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_POSTREAD);
  	    if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
! 		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_POSTWRITE);
  	    bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_ccb_dmamap);
  	}
  	ac->ac_flags &= ~AMR_CMD_MAPPED;
      }
  }
  
  /********************************************************************************
   * Take a command and give it to the controller, returns 0 if successful, or
   * EBUSY if the command should be retried later.
--- 1287,1330 ----
  
  	if (ac->ac_data != NULL) {
  	    if (ac->ac_flags & AMR_CMD_DATAIN)
! 		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap,
! 		    BUS_DMASYNC_POSTREAD);
  	    if (ac->ac_flags & AMR_CMD_DATAOUT)
! 		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap,
! 		    BUS_DMASYNC_POSTWRITE);
  	    bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
  	}
  
  	if (ac->ac_ccb_data != NULL) {
  	    if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
! 		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap,
! 		    BUS_DMASYNC_POSTREAD);
  	    if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
! 		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap,
! 		    BUS_DMASYNC_POSTWRITE);
  	    bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_ccb_dmamap);
  	}
  	ac->ac_flags &= ~AMR_CMD_MAPPED;
      }
  }
  
+ static void
+ amr_setup_data_dmamap(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
+ {
+     struct amr_command *ac = arg;
+     struct amr_softc *sc = ac->ac_sc;
+ 
+     amr_setup_dmamap(arg, segs, nsegs, err);
+ 
+     if (ac->ac_flags & AMR_CMD_DATAIN)
+ 	bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREREAD);
+     if (ac->ac_flags & AMR_CMD_DATAOUT)
+ 	bus_dmamap_sync(sc->amr_buffer_dmat,ac->ac_dmamap,BUS_DMASYNC_PREWRITE);
+     ac->ac_flags |= AMR_CMD_MAPPED;
+ 
+     amr_start1(sc, ac);
+ }
+    
  /********************************************************************************
   * Take a command and give it to the controller, returns 0 if successful, or
   * EBUSY if the command should be retried later.
***************
*** 1240,1259 ****
  static int
  amr_start(struct amr_command *ac)
  {
!     struct amr_softc	*sc = ac->ac_sc;
!     int			done, s, i;
  
      debug_called(3);
  
      /* mark command as busy so that polling consumer can tell */
      ac->ac_flags |= AMR_CMD_BUSY;
  
      /* get a command slot (freed in amr_done) */
      if (amr_getslot(ac))
  	return(EBUSY);
  
!     /* now we have a slot, we can map the command (unmapped in amr_complete) */
!     amr_mapcmd(ac);
  
      /* mark the new mailbox we are going to copy in as busy */
      ac->ac_mailbox.mb_busy = 1;
--- 1332,1368 ----
  static int
  amr_start(struct amr_command *ac)
  {
!     struct amr_softc *sc;
!     int error = 0;
  
      debug_called(3);
  
      /* mark command as busy so that polling consumer can tell */
+     sc = ac->ac_sc;
      ac->ac_flags |= AMR_CMD_BUSY;
  
      /* get a command slot (freed in amr_done) */
      if (amr_getslot(ac))
  	return(EBUSY);
  
!     /* Now we have a slot, we can map the command (unmapped in amr_complete). */
!     if ((error = amr_mapcmd(ac)) == ENOMEM) {
! 	/*
! 	 * Memroy resources are short, so free the slot and let this be tried
! 	 * later.
! 	 */
! 	sc->amr_busycmd[ac->ac_slot] = NULL;
! 	sc->amr_busyslots--;
!     }
! 
!     return (error);
! }
! 
! 
! static int
! amr_start1(struct amr_softc *sc, struct amr_command *ac)
! {
!     int			done, s, i;
  
      /* mark the new mailbox we are going to copy in as busy */
      ac->ac_mailbox.mb_busy = 1;
***************
*** 1363,1370 ****
  	    break;	/* no work */
  	}
      }
!     
      /* if we've completed any commands, try posting some more */
      if (result)
  	amr_startio(sc);
      
--- 1472,1480 ----
  	    break;	/* no work */
  	}
      }
! 
      /* if we've completed any commands, try posting some more */
+     sc->amr_state &= ~AMR_STATE_QUEUE_FRZN;
      if (result)
  	amr_startio(sc);
      
***************
*** 1375,1381 ****
      else
  #endif
  	amr_complete(sc, 0);
!     
      return(result);
  }
  
--- 1485,1491 ----
      else
  #endif
  	amr_complete(sc, 0);
! 
      return(result);
  }
  
***************
*** 1419,1424 ****
--- 1529,1535 ----
  	    wakeup(sc);
  	}
      }
+    amr_startio(sc);
  }
  
  /********************************************************************************
***************
*** 1798,1804 ****
  
      debug_called(1);
  
!     sc->amr_state |= AMR_STATE_CRASHDUMP;
  
      /* get ourselves a command buffer */
      if ((ac = amr_alloccmd(sc)) == NULL)
--- 1909,1915 ----
  
      debug_called(1);
  
!     sc->amr_state |= AMR_STATE_INTEN;
  
      /* get ourselves a command buffer */
      if ((ac = amr_alloccmd(sc)) == NULL)
***************
*** 1825,1831 ****
      if (ac != NULL)
  	amr_releasecmd(ac);
  
!     sc->amr_state &= ~AMR_STATE_CRASHDUMP;
  
      return (error);	
  }
--- 1936,1942 ----
      if (ac != NULL)
  	amr_releasecmd(ac);
  
!     sc->amr_state &= ~AMR_STATE_INTEN;
  
      return (error);	
  }
*** sys/dev/amr/amr_cam.c.orig	Mon Nov 11 05:19:10 2002
--- sys/dev/amr/amr_cam.c	Wed Mar  9 08:54:25 2005
***************
*** 139,148 ****
      /*
       * Allocate a devq for all our channels combined.  This should
       * allow for the maximum number of SCSI commands we will accept
!      * at one time.
       */
      if ((devq = cam_simq_alloc(AMR_MAX_SCSI_CMDS)) == NULL)
  	return(ENOMEM);
  
      /*
       * Iterate over our channels, registering them with CAM
--- 139,150 ----
      /*
       * Allocate a devq for all our channels combined.  This should
       * allow for the maximum number of SCSI commands we will accept
!      * at one time. Save the pointer in the softc so we can find it later
!      * during detach.
       */
      if ((devq = cam_simq_alloc(AMR_MAX_SCSI_CMDS)) == NULL)
  	return(ENOMEM);
+     sc->amr_cam_devq = devq;
  
      /*
       * Iterate over our channels, registering them with CAM
***************
*** 182,200 ****
  void
  amr_cam_detach(struct amr_softc *sc)
  {
!     int		chn, first;
  
!     for (chn = 0, first = 1; chn < sc->amr_maxchan; chn++) {
  
  	/*
  	 * If a sim was allocated for this channel, free it
  	 */
  	if (sc->amr_cam_sim[chn] != NULL) {
  	    xpt_bus_deregister(cam_sim_path(sc->amr_cam_sim[chn]));
! 	    cam_sim_free(sc->amr_cam_sim[chn], first ? TRUE : FALSE);
! 	    first = 0;
  	}
      }
  }
  
  /********************************************************************************
--- 184,205 ----
  void
  amr_cam_detach(struct amr_softc *sc)
  {
!     int		chn;
  
!     for (chn = 0; chn < sc->amr_maxchan; chn++) {
  
  	/*
  	 * If a sim was allocated for this channel, free it
  	 */
  	if (sc->amr_cam_sim[chn] != NULL) {
  	    xpt_bus_deregister(cam_sim_path(sc->amr_cam_sim[chn]));
! 	    cam_sim_free(sc->amr_cam_sim[chn], FALSE);
  	}
      }
+ 
+     /* Now free the devq */
+     if (sc->amr_cam_devq != NULL)
+ 	cam_simq_free(sc->amr_cam_devq);
  }
  
  /********************************************************************************
***************
*** 458,464 ****
  	goto out;
      }
  
!     ac->ac_flags |= AMR_CMD_DATAOUT;
  
      ac->ac_ccb_data = csio->data_ptr;
      ac->ac_ccb_length = csio->dxfer_len;
--- 463,469 ----
  	goto out;
      }
  
!     ac->ac_flags |= AMR_CMD_DATAOUT | AMR_CMD_DATAIN;
  
      ac->ac_ccb_data = csio->data_ptr;
      ac->ac_ccb_length = csio->dxfer_len;
***************
*** 516,522 ****
  
      /* XXX note that we're ignoring ac->ac_status - good idea? */
  
!     debug(1, "status 0x%x  scsi_status 0x%x", ac->ac_status, ap->ap_scsi_status);
  
      /*
       * Hide disks from CAM so that they're not picked up and treated as 'normal' disks.
--- 521,527 ----
  
      /* XXX note that we're ignoring ac->ac_status - good idea? */
  
!     debug(1, "status 0x%x  AP scsi_status 0x%x", ac->ac_status, ap->ap_scsi_status);
  
      /*
       * Hide disks from CAM so that they're not picked up and treated as 'normal' disks.
***************
*** 579,585 ****
  
      /* XXX note that we're ignoring ac->ac_status - good idea? */
  
!     debug(1, "status 0x%x  scsi_status 0x%x", ac->ac_status, aep->ap_scsi_status);
  
      /*
       * Hide disks from CAM so that they're not picked up and treated as 'normal' disks.
--- 584,590 ----
  
      /* XXX note that we're ignoring ac->ac_status - good idea? */
  
!     debug(1, "status 0x%x  AEP scsi_status 0x%x", ac->ac_status, aep->ap_scsi_status);
  
      /*
       * Hide disks from CAM so that they're not picked up and treated as 'normal' disks.
*** sys/dev/amr/amr_disk.c.orig	Wed Oct 29 01:11:38 2003
--- sys/dev/amr/amr_disk.c	Wed Mar  9 09:02:44 2005
***************
*** 53,59 ****
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
!  * $FreeBSD: /repoman/r/ncvs/src/sys/dev/amr/amr_disk.c,v 1.5.2.6 2003/10/29 09:11:38 ps Exp $
   */
  
  /*
--- 53,59 ----
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
!  * $FreeBSD: src/sys/dev/amr/amr_disk.c,v 1.5.2.6 2003/10/29 09:11:38 ps Exp $
   */
  
  /*
***************
*** 215,224 ****
      if ((error = disk_dumpcheck(dev, &count, &blkno, &secsize)))
          return(error);
  
!     amr_sc  = (struct amr_softc *)amrd_sc->amrd_controller;
! 
!     if (!amrd_sc || !amr_sc)
  	return(ENXIO);
  
      blkcnt = howmany(PAGE_SIZE, secsize);
  
--- 215,223 ----
      if ((error = disk_dumpcheck(dev, &count, &blkno, &secsize)))
          return(error);
  
!     if (amrd_sc == NULL)
  	return(ENXIO);
+     amr_sc  = (struct amr_softc *)amrd_sc->amrd_controller;
  
      blkcnt = howmany(PAGE_SIZE, secsize);
  
*** sys/dev/amr/amr_pci.c.orig	Wed Dec  8 10:53:23 2004
--- sys/dev/amr/amr_pci.c	Wed Mar  9 09:09:58 2005
***************
*** 25,31 ****
   * SUCH DAMAGE.
   *
   * Copyright (c) 2002 Eric Moore
!  * Copyright (c) 2002 LSI Logic Corporation
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
--- 25,31 ----
   * SUCH DAMAGE.
   *
   * Copyright (c) 2002 Eric Moore
!  * Copyright (c) 2002, 2004 LSI Logic Corporation
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
***************
*** 127,132 ****
--- 127,134 ----
      {0x101e, 0x1960, 0},
      {0x1000, 0x1960, PROBE_SIGNATURE},
      {0x1000, 0x0407, 0},
+     {0x1000, 0x0408, 0},
+     {0x1000, 0x0409, 0},
      {0x1028, 0x000e, PROBE_SIGNATURE}, /* perc4/di i960 */
      {0x1028, 0x000f, 0}, /* perc4/di Verde*/
      {0x1028, 0x0013, 0}, /* perc4/di */
***************
*** 150,156 ****
  		if ((sig != AMR_SIGNATURE_1) && (sig != AMR_SIGNATURE_2))
  		    continue;
  	    }
! 	    device_set_desc(dev, "LSILogic MegaRAID");
  	    return(-10);	/* allow room to be overridden */
  	}
      }
--- 152,158 ----
  		if ((sig != AMR_SIGNATURE_1) && (sig != AMR_SIGNATURE_2))
  		    continue;
  	    }
! 	    device_set_desc(dev, LSI_DESC_PCI);
  	    return(-10);	/* allow room to be overridden */
  	}
      }
***************
*** 181,186 ****
--- 183,189 ----
       */
      command = pci_read_config(dev, PCIR_COMMAND, 1);
      if ((pci_get_device(dev) == 0x1960) || (pci_get_device(dev) == 0x0407) ||
+ 	(pci_get_device(dev) == 0x0408) || (pci_get_device(dev) == 0x0409) ||
  	(pci_get_device(dev) == 0x000e) || (pci_get_device(dev) == 0x000f) ||
  	(pci_get_device(dev) == 0x0013)) {
  	/*
***************
*** 251,257 ****
  			   NULL, NULL, 			/* filter, filterarg */
  			   MAXBSIZE, AMR_NSEG,		/* maxsize, nsegments */
  			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
! 			   BUS_DMA_ALLOCNOW,		/* flags */
  			   &sc->amr_parent_dmat)) {
  	device_printf(dev, "can't allocate parent DMA tag\n");
  	goto out;
--- 254,260 ----
  			   NULL, NULL, 			/* filter, filterarg */
  			   MAXBSIZE, AMR_NSEG,		/* maxsize, nsegments */
  			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
! 			   0,				/* flags */
  			   &sc->amr_parent_dmat)) {
  	device_printf(dev, "can't allocate parent DMA tag\n");
  	goto out;
***************
*** 262,273 ****
       */
      if (bus_dma_tag_create(sc->amr_parent_dmat,		/* parent */
  			   1, 0,			/* alignment, boundary */
! 			   BUS_SPACE_MAXADDR,		/* lowaddr */
  			   BUS_SPACE_MAXADDR,		/* highaddr */
  			   NULL, NULL,			/* filter, filterarg */
  			   MAXBSIZE, AMR_NSEG,		/* maxsize, nsegments */
! 			   BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
! 			   0,				/* flags */
  			   &sc->amr_buffer_dmat)) {
          device_printf(sc->amr_dev, "can't allocate buffer DMA tag\n");
  	goto out;
--- 265,276 ----
       */
      if (bus_dma_tag_create(sc->amr_parent_dmat,		/* parent */
  			   1, 0,			/* alignment, boundary */
! 			   BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
  			   BUS_SPACE_MAXADDR,		/* highaddr */
  			   NULL, NULL,			/* filter, filterarg */
  			   MAXBSIZE, AMR_NSEG,		/* maxsize, nsegments */
! 			   MAXBSIZE,			/* maxsegsize */
! 			   BUS_DMA_ALLOCNOW,		/* flags */
  			   &sc->amr_buffer_dmat)) {
          device_printf(sc->amr_dev, "can't allocate buffer DMA tag\n");
  	goto out;
***************
*** 502,508 ****
      segsize = sizeof(struct amr_sgentry) * AMR_NSEG * AMR_MAXCMD;
      error = bus_dma_tag_create(sc->amr_parent_dmat, 	/* parent */
  			       1, 0, 			/* alignment, boundary */
! 			       BUS_SPACE_MAXADDR,	/* lowaddr */
  			       BUS_SPACE_MAXADDR, 	/* highaddr */
  			       NULL, NULL, 		/* filter, filterarg */
  			       segsize, 1,		/* maxsize, nsegments */
--- 505,511 ----
      segsize = sizeof(struct amr_sgentry) * AMR_NSEG * AMR_MAXCMD;
      error = bus_dma_tag_create(sc->amr_parent_dmat, 	/* parent */
  			       1, 0, 			/* alignment, boundary */
! 			       BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
  			       BUS_SPACE_MAXADDR, 	/* highaddr */
  			       NULL, NULL, 		/* filter, filterarg */
  			       segsize, 1,		/* maxsize, nsegments */
***************
*** 572,578 ****
       */
      error = bus_dma_tag_create(sc->amr_parent_dmat,	/* parent */
  			       16, 0,			/* alignment, boundary */
! 			       BUS_SPACE_MAXADDR,	/* lowaddr */
  			       BUS_SPACE_MAXADDR,	/* highaddr */
  			       NULL, NULL,		/* filter, filterarg */
  			       sizeof(struct amr_mailbox) + 16, 1, /* maxsize, nsegments */
--- 575,581 ----
       */
      error = bus_dma_tag_create(sc->amr_parent_dmat,	/* parent */
  			       16, 0,			/* alignment, boundary */
! 			       BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
  			       BUS_SPACE_MAXADDR,	/* highaddr */
  			       NULL, NULL,		/* filter, filterarg */
  			       sizeof(struct amr_mailbox) + 16, 1, /* maxsize, nsegments */
*** sys/dev/amr/amrreg.h.orig	Mon Nov 11 05:19:10 2002
--- sys/dev/amr/amrreg.h	Wed Mar  9 09:14:35 2005
***************
*** 52,58 ****
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
!  *      $FreeBSD: /repoman/r/ncvs/src/sys/dev/amr/amrreg.h,v 1.1.2.4 2002/11/11 13:19:10 emoore Exp $
   */
  
  /********************************************************************************
--- 52,58 ----
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
!  *      $FreeBSD: src/sys/dev/amr/amrreg.h,v 1.1.2.4 2002/11/11 13:19:10 emoore Exp $
   */
  
  /********************************************************************************
***************
*** 81,87 ****
  #define AMR_LIMITCMD		120		/* maximum count of outstanding commands */
  #define AMR_MAXLD      		40
  
! #define AMR_MAX_CHANNELS	4
  #define AMR_MAX_TARGETS		15
  #define AMR_MAX_LUNS		7
  #define AMR_MAX_SCSI_CMDS	(15 * AMR_MAX_CHANNELS)	/* one for every target? */
--- 81,87 ----
  #define AMR_LIMITCMD		120		/* maximum count of outstanding commands */
  #define AMR_MAXLD      		40
  
! #define AMR_MAX_CHANNELS	8
  #define AMR_MAX_TARGETS		15
  #define AMR_MAX_LUNS		7
  #define AMR_MAX_SCSI_CMDS	(15 * AMR_MAX_CHANNELS)	/* one for every target? */
*** sys/dev/amr/amrvar.h.orig	Thu Jul 22 09:35:18 2004
--- sys/dev/amr/amrvar.h	Wed Mar  9 09:19:20 2005
***************
*** 59,64 ****
--- 59,66 ----
  # include <sys/taskqueue.h>
  #endif
  
+ #define LSI_DESC_PCI "LSILogic MegaRAID 1.51"
+ 
  #ifdef AMR_DEBUG
  # define debug(level, fmt, args...)	do {if (level <= AMR_DEBUG) printf("%s: " fmt "\n", __func__ , ##args);} while(0)
  # define debug_called(level)		do {if (level <= AMR_DEBUG) printf("%s: called\n", __func__);} while(0)
***************
*** 186,191 ****
--- 188,194 ----
  #define AMR_STATE_INTEN		(1<<2)
  #define AMR_STATE_SHUTDOWN	(1<<3)
  #define AMR_STATE_CRASHDUMP	(1<<4)
+ #define AMR_STATE_QUEUE_FRZN	(1<<5)
  
      /* per-controller queues */
      struct bio_queue_head 	amr_bioq;		/* pending I/O with no commands */
***************
*** 199,204 ****
--- 202,208 ----
      /* CAM attachments for passthrough */
      struct cam_sim		*amr_cam_sim[AMR_MAX_CHANNELS];
      TAILQ_HEAD(, ccb_hdr)	amr_cam_ccbq;
+     struct cam_devq		*amr_cam_devq;
  
      /* control device */
      dev_t			amr_dev_t;
***************
*** 212,217 ****
--- 216,222 ----
      int				(* amr_submit_command)(struct amr_softc *sc);
      int				(* amr_get_work)(struct amr_softc *sc, struct amr_mailbox *mbsave);
      int				(*amr_poll_command)(struct amr_command *ac);
+     int				(*amr_poll_command1)(struct amr_softc *sc, struct amr_command *ac);
      int 			support_ext_cdb;	/* greater than 10 byte cdb support */
  
      /* misc glue */

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6.2.1.2.2.20050310000250.05746d80>