Can FreeBSD be installed on DellPowerEdge2800 ?

David Sze dsze at alumni.uwaterloo.ca
Tue Mar 8 23:58:55 GMT 2005


On Wed, Mar 02, 2005 at 08:25:40AM -0600, Art Mason wrote:
>
>Vinny Abello wrote:
>>
>>At 05:50 PM 3/1/2005, Art Mason wrote:
>>>
>>>Indeed, just installed on a customer's server last night, and I build 
>>>SMP support into the GENERIC kernel this morning.  Only issues I 
>>>encountered has to do w/ recognizing the full 4GB of RAM, but this 
>>>apparently has some compatibility issues w/ the amr driver.
>>>As per Holger's comments about disabling USB in BIOS, this is a good 
>>>suggestion, since the DRAC apparently causes some IRQ issues w/ the 
>>>PS/2 keyboard controller, or something along those lines.  Regardless, 
>>>these 2850 boxes are stupid fast, and I'm looking forward to 
>>>benchmarking 5.3 on them.
>>
>>
>>FYI, the architecture of the 2850 (assuming it is similar to your 2800) 
>>requires that you enable PAE support in your kernel of whatever OS you 
>>run to address the full 4GB of RAM. This is due in some part because of 
>>the memory mapping that was done for the PCI express bus and/or onboard 
>>Perc controller (per Dell tech support). We've run into this with all of 
>>our 2850's with various OS's and enabling PAE (per Dell's advice) fixes it.
>
>
>Yeah, I cam across that on some mailing list archives, but saw some 
>additional references that this can cause issues with the amr driver. 
>Have you experienced any instability issues with the amr driver and PAE 
>enabled?  If not, then I'll give this a shot on one of our lab boxes for 
>testing.  Thanks for the suggestion, BTW.


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.

-------------- next part --------------
*** sys/dev/amr/amr.c.orig	Thu Jul 22 09:35:18 2004
--- sys/dev/amr/amr.c	Tue Mar  8 15:11:33 2005
***************
*** 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
--- 132,146 ----
   * 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 ****
--- 153,159 ----
  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 ****
--- 221,227 ----
  	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;
***************
*** 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;
--- 686,696 ----
      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 ****
--- 800,809 ----
      /* 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 ****
--- 977,993 ----
      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,989 ****
  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;
--- 996,1026 ----
  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_CRASHDUMP) == 0) {
  	count=0;
***************
*** 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);
          }
--- 1033,1040 ----
  
  	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);
  }
--- 1064,1072 ----
      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
--- 1149,1162 ----
      } 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;
--- 1180,1200 ----
  	} 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;
--- 1202,1243 ----
  	} 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
--- 1245,1271 ----
      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;
! 	    }
  	}
      }
+     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.
--- 1280,1326 ----
  
  	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);
+ 	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);
  	}
  	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;
--- 1328,1364 ----
  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);
      
--- 1468,1476 ----
  	    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);
  }
  
--- 1481,1487 ----
      else
  #endif
  	amr_complete(sc, 0);
! 
      return(result);
  }
  
***************
*** 1419,1424 ****
--- 1525,1531 ----
  	    wakeup(sc);
  	}
      }
+    amr_startio(sc);
  }
  
  /********************************************************************************
*** sys/dev/amr/amr_cam.c.orig	Mon Nov 11 05:19:10 2002
--- sys/dev/amr/amr_cam.c	Tue Mar  8 15:11:33 2005
***************
*** 458,464 ****
  	goto out;
      }
  
!     ac->ac_flags |= AMR_CMD_DATAOUT;
  
      ac->ac_ccb_data = csio->data_ptr;
      ac->ac_ccb_length = csio->dxfer_len;
--- 458,464 ----
  	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.
--- 516,522 ----
  
      /* 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.
--- 579,585 ----
  
      /* 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_pci.c.orig	Wed Dec  8 10:53:23 2004
--- sys/dev/amr/amr_pci.c	Tue Mar  8 15:11:33 2005
***************
*** 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;
--- 251,257 ----
  			   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;
--- 262,273 ----
       */
      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 */
--- 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_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 */
--- 572,578 ----
       */
      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/amrvar.h.orig	Thu Jul 22 09:35:18 2004
--- sys/dev/amr/amrvar.h	Tue Mar  8 15:11:34 2005
***************
*** 186,191 ****
--- 186,192 ----
  #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 */
***************
*** 212,217 ****
--- 213,219 ----
      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 */


More information about the freebsd-stable mailing list