patch-1.3.53 linux/drivers/scsi/scsi.c
Next file: linux/drivers/scsi/scsi_ioctl.c
Previous file: linux/drivers/scsi/aha1740.c
Back to the patch index
Back to the overall index
- Lines: 279
- Date:
Sat Dec 30 22:38:29 1995
- Orig file:
v1.3.52/linux/drivers/scsi/scsi.c
- Orig date:
Sat Dec 30 15:50:53 1995
diff -u --recursive --new-file v1.3.52/linux/drivers/scsi/scsi.c linux/drivers/scsi/scsi.c
@@ -58,6 +58,21 @@
#define INTERNAL_ERROR (panic ("Internal error in file %s, line %d.\n", __FILE__, __LINE__))
+/*
+ * PAGE_SIZE must be a multiple of the sector size (512). True
+ * for all reasonably recent architectures (even the VAX...).
+ */
+#define SECTOR_SIZE 512
+#define SECTORS_PER_PAGE (PAGE_SIZE/SECTOR_SIZE)
+
+#if SECTORS_PER_PAGE <= 8
+ typedef unsigned char FreeSectorBitmap;
+#elif SECTORS_PER_PAGE <= 32
+ typedef unsigned int FreeSectorBitmap;
+#else
+# error You lose.
+#endif
+
static void scsi_done (Scsi_Cmnd *SCpnt);
static int update_timeout (Scsi_Cmnd *, int);
static void print_inquiry(unsigned char *data);
@@ -68,7 +83,7 @@
void scsi_build_commandblocks(Scsi_Device * SDpnt);
-static unsigned char * dma_malloc_freelist = NULL;
+static FreeSectorBitmap * dma_malloc_freelist = NULL;
static int scsi_need_isa_bounce_buffers;
static unsigned int dma_sectors = 0;
unsigned int dma_free_sectors = 0;
@@ -2145,8 +2160,6 @@
return oldto;
}
-#define MALLOC_PAGEBITS 12
-
#ifdef CONFIG_MODULES
static int scsi_register_host(Scsi_Host_Template *);
static void scsi_unregister_host(Scsi_Host_Template *);
@@ -2157,7 +2170,7 @@
unsigned int nbits, mask;
unsigned long flags;
int i, j;
- if((len & 0x1ff) || len > (1<<MALLOC_PAGEBITS))
+ if(len % SECTOR_SIZE != 0 || len > PAGE_SIZE)
return NULL;
save_flags(flags);
@@ -2165,8 +2178,8 @@
nbits = len >> 9;
mask = (1 << nbits) - 1;
- for(i=0;i < (dma_sectors >> (MALLOC_PAGEBITS - 9)); i++)
- for(j=0; j<=(sizeof(*dma_malloc_freelist) * 8) - nbits; j++){
+ for(i=0;i < dma_sectors / SECTORS_PER_PAGE; i++)
+ for(j=0; j<=SECTORS_PER_PAGE - nbits; j++){
if ((dma_malloc_freelist[i] & (mask << j)) == 0){
dma_malloc_freelist[i] |= (mask << j);
restore_flags(flags);
@@ -2183,43 +2196,38 @@
int scsi_free(void *obj, unsigned int len)
{
- int page, sector, nbits, mask;
- long offset;
+ unsigned int page, sector, nbits, mask;
unsigned long flags;
#ifdef DEBUG
printk("scsi_free %p %d\n",obj, len);
#endif
- offset = -1;
- for (page = 0; page < (dma_sectors >> 3); page++)
- if ((unsigned long) obj >= (unsigned long) dma_malloc_pages[page] &&
- (unsigned long) obj < (unsigned long) dma_malloc_pages[page]
- + (1 << MALLOC_PAGEBITS))
+ for (page = 0; page < dma_sectors / SECTORS_PER_PAGE; page++) {
+ unsigned long page_addr = (unsigned long) dma_malloc_pages[page];
+ if ((unsigned long) obj >= page_addr &&
+ (unsigned long) obj < page_addr + PAGE_SIZE)
{
- offset = ((unsigned long) obj) - ((unsigned long)dma_malloc_pages[page]);
- break;
+ sector = (((unsigned long) obj) - page_addr) >> 9;
+
+ nbits = len >> 9;
+ mask = (1 << nbits) - 1;
+
+ if ((mask << sector) >= (1 << SECTORS_PER_PAGE))
+ panic ("scsi_free:Bad memory alignment");
+
+ save_flags(flags);
+ cli();
+ if((dma_malloc_freelist[page] & (mask << sector)) != (mask<<sector))
+ panic("scsi_free:Trying to free unused memory");
+
+ dma_free_sectors += nbits;
+ dma_malloc_freelist[page] &= ~(mask << sector);
+ restore_flags(flags);
+ return 0;
}
-
- if (page == (dma_sectors >> 3)) panic("scsi_free:Bad offset");
- sector = offset >> 9;
- if(sector >= dma_sectors) panic ("scsi_free:Bad page");
-
- sector = (offset >> 9) & (sizeof(*dma_malloc_freelist) * 8 - 1);
- nbits = len >> 9;
- mask = (1 << nbits) - 1;
-
- if ((mask << sector) > 0xffff) panic ("scsi_free:Bad memory alignment");
-
- save_flags(flags);
- cli();
- if((dma_malloc_freelist[page] & (mask << sector)) != (mask<<sector))
- panic("scsi_free:Trying to free unused memory");
-
- dma_free_sectors += nbits;
- dma_malloc_freelist[page] &= ~(mask << sector);
- restore_flags(flags);
- return 0;
+ }
+ panic("scsi_free:Bad offset");
}
@@ -2521,11 +2529,12 @@
static void resize_dma_pool(void)
{
int i;
+ unsigned long size;
struct Scsi_Host * shpnt;
struct Scsi_Host * host = NULL;
Scsi_Device * SDpnt;
unsigned long flags;
- unsigned char * new_dma_malloc_freelist = NULL;
+ FreeSectorBitmap * new_dma_malloc_freelist = NULL;
unsigned int new_dma_sectors = 0;
unsigned int new_need_isa_buffer = 0;
unsigned char ** new_dma_malloc_pages = NULL;
@@ -2538,14 +2547,15 @@
if( dma_free_sectors != dma_sectors )
panic("SCSI DMA pool memory leak %d %d\n",dma_free_sectors,dma_sectors);
- for(i=0; i < dma_sectors >> 3; i++)
+ for(i=0; i < dma_sectors / SECTORS_PER_PAGE; i++)
scsi_init_free(dma_malloc_pages[i], PAGE_SIZE);
if (dma_malloc_pages)
scsi_init_free((char *) dma_malloc_pages,
- (dma_sectors>>3)*sizeof(*dma_malloc_pages));
+ (dma_sectors / SECTORS_PER_PAGE)*sizeof(*dma_malloc_pages));
dma_malloc_pages = NULL;
if (dma_malloc_freelist)
- scsi_init_free(dma_malloc_freelist, dma_sectors>>3);
+ scsi_init_free((char *) dma_malloc_freelist,
+ (dma_sectors / SECTORS_PER_PAGE)*sizeof(*dma_malloc_freelist));
dma_malloc_freelist = NULL;
dma_sectors = 0;
dma_free_sectors = 0;
@@ -2553,7 +2563,7 @@
}
/* Next, check to see if we need to extend the DMA buffer pool */
- new_dma_sectors = 16; /* Base value we use */
+ new_dma_sectors = 2*SECTORS_PER_PAGE; /* Base value we use */
if (high_memory-1 > ISA_DMA_THRESHOLD)
scsi_need_isa_bounce_buffers = 1;
@@ -2562,7 +2572,7 @@
if (scsi_devicelist)
for(shpnt=scsi_hostlist; shpnt; shpnt = shpnt->next)
- new_dma_sectors += 8; /* Increment for each host */
+ new_dma_sectors += SECTORS_PER_PAGE; /* Increment for each host */
for (SDpnt=scsi_devices; SDpnt; SDpnt = SDpnt->next) {
host = SDpnt->host;
@@ -2581,6 +2591,7 @@
}
}
+ /* limit DMA memory to 32MB: */
new_dma_sectors = (new_dma_sectors + 15) & 0xfff0;
/*
@@ -2593,22 +2604,20 @@
if (new_dma_sectors)
{
- new_dma_malloc_freelist = (unsigned char *)
- scsi_init_malloc(new_dma_sectors >> 3, GFP_ATOMIC);
- memset(new_dma_malloc_freelist, 0, new_dma_sectors >> 3);
-
- new_dma_malloc_pages = (unsigned char **)
- scsi_init_malloc((new_dma_sectors>>3)*sizeof(*new_dma_malloc_pages),
- GFP_ATOMIC);
- memset(new_dma_malloc_pages, 0,
- (new_dma_sectors>>3)*sizeof(*new_dma_malloc_pages));
+ size = (new_dma_sectors / SECTORS_PER_PAGE)*sizeof(FreeSectorBitmap);
+ new_dma_malloc_freelist = (FreeSectorBitmap *) scsi_init_malloc(size, GFP_ATOMIC);
+ memset(new_dma_malloc_freelist, 0, size);
+
+ size = (new_dma_sectors / SECTORS_PER_PAGE)*sizeof(*new_dma_malloc_pages);
+ new_dma_malloc_pages = (unsigned char **) scsi_init_malloc(size, GFP_ATOMIC);
+ memset(new_dma_malloc_pages, 0, size);
}
/*
* If we need more buffers, expand the list.
*/
if( new_dma_sectors > dma_sectors ) {
- for(i=dma_sectors >> 3; i< new_dma_sectors >> 3; i++)
+ for(i=dma_sectors / SECTORS_PER_PAGE; i< new_dma_sectors / SECTORS_PER_PAGE; i++)
new_dma_malloc_pages[i] = (unsigned char *)
scsi_init_malloc(PAGE_SIZE, GFP_ATOMIC | GFP_DMA);
}
@@ -2620,17 +2629,17 @@
cli();
if (dma_malloc_freelist)
{
- memcpy(new_dma_malloc_freelist, dma_malloc_freelist, dma_sectors >> 3);
- scsi_init_free(dma_malloc_freelist, dma_sectors>>3);
+ size = (dma_sectors / SECTORS_PER_PAGE)*sizeof(FreeSectorBitmap);
+ memcpy(new_dma_malloc_freelist, dma_malloc_freelist, size);
+ scsi_init_free((char *) dma_malloc_freelist, size);
}
dma_malloc_freelist = new_dma_malloc_freelist;
if (dma_malloc_pages)
{
- memcpy(new_dma_malloc_pages, dma_malloc_pages,
- (dma_sectors>>3)*sizeof(*dma_malloc_pages));
- scsi_init_free((char *) dma_malloc_pages,
- (dma_sectors>>3)*sizeof(*dma_malloc_pages));
+ size = (dma_sectors / SECTORS_PER_PAGE)*sizeof(*dma_malloc_pages);
+ memcpy(new_dma_malloc_pages, dma_malloc_pages, size);
+ scsi_init_free((char *) dma_malloc_pages, size);
}
dma_free_sectors += new_dma_sectors - dma_sectors;
@@ -3111,6 +3120,8 @@
extern struct symbol_table scsi_symbol_table;
int init_module(void) {
+ unsigned long size;
+
/*
* This makes /proc/scsi visible.
*/
@@ -3127,7 +3138,7 @@
#endif
- dma_sectors = PAGE_SIZE / 512;
+ dma_sectors = PAGE_SIZE / SECTOR_SIZE;
dma_free_sectors= dma_sectors;
/*
* Set up a minimal DMA buffer list - this will be used during scan_scsis
@@ -3135,13 +3146,13 @@
*/
/* One bit per sector to indicate free/busy */
- dma_malloc_freelist = (unsigned char *)
- scsi_init_malloc(dma_sectors >> 3, GFP_ATOMIC);
- memset(dma_malloc_freelist, 0, dma_sectors >> 3);
-
+ size = (dma_sectors / SECTORS_PER_PAGE)*sizeof(FreeSectorBitmap);
+ dma_malloc_freelist = (unsigned char *) scsi_init_malloc(size, GFP_ATOMIC);
+ memset(dma_malloc_freelist, 0, size);
+
/* One pointer per page for the page list */
dma_malloc_pages = (unsigned char **)
- scsi_init_malloc((dma_sectors >> 3)*sizeof(*dma_malloc_pages), GFP_ATOMIC);
+ scsi_init_malloc((dma_sectors / SECTORS_PER_PAGE)*sizeof(*dma_malloc_pages), GFP_ATOMIC);
dma_malloc_pages[0] = (unsigned char *)
scsi_init_malloc(PAGE_SIZE, GFP_ATOMIC | GFP_DMA);
return 0;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this