};
MODULE_DEVICE_TABLE(pci,dptids);
-static void adpt_exit(void);
-
-static int adpt_detect(void)
+static int adpt_detect(struct scsi_host_template* sht)
{
struct pci_dev *pDev = NULL;
adpt_hba* pHba;
+ adpt_init();
+
PINFO("Detecting Adaptec I2O RAID controllers...\n");
/* search for all Adatpec I2O RAID cards */
while ((pDev = pci_get_device( PCI_DPT_VENDOR_ID, PCI_ANY_ID, pDev))) {
if(pDev->device == PCI_DPT_DEVICE_ID ||
pDev->device == PCI_DPT_RAPTOR_DEVICE_ID){
- if(adpt_install_hba(pDev) ){
+ if(adpt_install_hba(sht, pDev) ){
PERROR("Could not Init an I2O RAID device\n");
PERROR("Will not try to detect others.\n");
return hba_count-1;
}
for (pHba = hba_chain; pHba; pHba = pHba->next) {
- if (adpt_scsi_register(pHba) < 0) {
+ if( adpt_scsi_register(pHba,sht) < 0){
adpt_i2o_delete_hba(pHba);
continue;
}
pHba->initialized = TRUE;
pHba->state &= ~DPTI_STATE_RESET;
- scsi_scan_host(pHba->host);
}
// Register our control device node
// nodes will need to be created in /dev to access this
// the nodes can not be created from within the driver
if (hba_count && register_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER, &adpt_fops)) {
- adpt_exit();
+ adpt_i2o_sys_shutdown();
return 0;
}
return hba_count;
}
-static int adpt_release(adpt_hba *pHba)
+/*
+ * scsi_unregister will be called AFTER we return.
+ */
+static int adpt_release(struct Scsi_Host *host)
{
- struct Scsi_Host *shost = pHba->host;
- scsi_remove_host(shost);
+ adpt_hba* pHba = (adpt_hba*) host->hostdata[0];
// adpt_i2o_quiesce_hba(pHba);
adpt_i2o_delete_hba(pHba);
- scsi_host_put(shost);
+ scsi_unregister(host);
return 0;
}
#endif
-static int adpt_install_hba(struct pci_dev* pDev)
+static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev)
{
adpt_hba* pHba = NULL;
}
pci_set_master(pDev);
- if (pci_set_dma_mask(pDev, DMA_64BIT_MASK) &&
- pci_set_dma_mask(pDev, DMA_32BIT_MASK))
+ if (pci_set_dma_mask(pDev, DMA_32BIT_MASK))
return -EINVAL;
base_addr0_phys = pci_resource_start(pDev,0);
}
// Allocate and zero the data structure
- pHba = kmalloc(sizeof(adpt_hba), GFP_KERNEL);
- if( pHba == NULL) {
- if(msg_addr_virt != base_addr_virt){
+ pHba = kzalloc(sizeof(adpt_hba), GFP_KERNEL);
+ if (!pHba) {
+ if (msg_addr_virt != base_addr_virt)
iounmap(msg_addr_virt);
- }
iounmap(base_addr_virt);
pci_release_regions(pDev);
return -ENOMEM;
}
- memset(pHba, 0, sizeof(adpt_hba));
mutex_lock(&adpt_configuration_lock);
mutex_lock(&adpt_configuration_lock);
+ // scsi_unregister calls our adpt_release which
+ // does a quiese
if(pHba->host){
free_irq(pHba->host->irq, pHba);
}
}
+static int adpt_init(void)
+{
+ printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
+#ifdef REBOOT_NOTIFIER
+ register_reboot_notifier(&adpt_reboot_notifier);
+#endif
+
+ return 0;
+}
+
+
static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun)
{
struct adpt_device* d;
}
+static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht)
+{
+ struct Scsi_Host *host = NULL;
+
+ host = scsi_register(sht, sizeof(adpt_hba*));
+ if (host == NULL) {
+ printk ("%s: scsi_register returned NULL\n",pHba->name);
+ return -1;
+ }
+ host->hostdata[0] = (unsigned long)pHba;
+ pHba->host = host;
+
+ host->irq = pHba->pDev->irq;
+ /* no IO ports, so don't have to set host->io_port and
+ * host->n_io_port
+ */
+ host->io_port = 0;
+ host->n_io_port = 0;
+ /* see comments in scsi_host.h */
+ host->max_id = 16;
+ host->max_lun = 256;
+ host->max_channel = pHba->top_scsi_channel + 1;
+ host->cmd_per_lun = 1;
+ host->unique_id = (uint) pHba;
+ host->sg_tablesize = pHba->sg_tablesize;
+ host->can_queue = pHba->post_fifo_size;
+
+ return 0;
+}
+
+
static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd)
{
adpt_hba* pHba;
// copy over the request sense data if it was a check
// condition status
- if(dev_status == 0x02 /*CHECK_CONDITION*/) {
- u32 len = sizeof(cmd->sense_buffer);
- len = (len > 40) ? 40 : len;
+ if (dev_status == SAM_STAT_CHECK_CONDITION) {
+ u32 len = min(SCSI_SENSE_BUFFERSIZE, 40);
// Copy over the sense data
memcpy_fromio(cmd->sense_buffer, (reply+28) , len);
if(cmd->sense_buffer[0] == 0x70 /* class 7 */ &&
msg=(u32 __iomem *)(pHba->msg_addr_virt+m);
- status = kmalloc(4,GFP_KERNEL|ADDR32);
- if (status==NULL) {
+ status = kzalloc(4, GFP_KERNEL|ADDR32);
+ if (!status) {
adpt_send_nop(pHba, m);
printk(KERN_WARNING"%s: IOP reset failed - no free memory.\n",
pHba->name);
return -ENOMEM;
}
- memset(status, 0, 4);
writel(EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6, &msg[0]);
writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]);
kfree(pHba->reply_pool);
- pHba->reply_pool = kmalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
- if(!pHba->reply_pool){
- printk(KERN_ERR"%s: Could not allocate reply pool\n",pHba->name);
- return -1;
+ pHba->reply_pool = kzalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
+ if (!pHba->reply_pool) {
+ printk(KERN_ERR "%s: Could not allocate reply pool\n", pHba->name);
+ return -ENOMEM;
}
- memset(pHba->reply_pool, 0 , pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4);
ptr = pHba->reply_pool;
for(i = 0; i < pHba->reply_fifo_size; i++) {
kfree(sys_tbl);
- sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL|ADDR32);
- if(!sys_tbl) {
+ sys_tbl = kzalloc(sys_tbl_len, GFP_KERNEL|ADDR32);
+ if (!sys_tbl) {
printk(KERN_WARNING "SysTab Set failed. Out of memory.\n");
return -ENOMEM;
}
- memset(sys_tbl, 0, sys_tbl_len);
sys_tbl->num_entries = hba_count;
sys_tbl->version = I2OVERSION;
#endif
-static struct scsi_host_template adpt_template = {
+static struct scsi_host_template driver_template = {
.name = "dpt_i2o",
.proc_name = "dpt_i2o",
.proc_info = adpt_proc_info,
+ .detect = adpt_detect,
+ .release = adpt_release,
.info = adpt_info,
.queuecommand = adpt_queue,
.eh_abort_handler = adpt_abort,
.cmd_per_lun = 1,
.use_clustering = ENABLE_CLUSTERING,
};
-
-static s32 adpt_scsi_register(adpt_hba* pHba)
-{
- struct Scsi_Host *host;
-
- host = scsi_host_alloc(&adpt_template, sizeof(adpt_hba*));
- if (host == NULL) {
- printk ("%s: scsi_host_alloc returned NULL\n",pHba->name);
- return -1;
- }
- host->hostdata[0] = (unsigned long)pHba;
- pHba->host = host;
-
- host->irq = pHba->pDev->irq;
- /* no IO ports, so don't have to set host->io_port and
- * host->n_io_port
- */
- host->io_port = 0;
- host->n_io_port = 0;
- /* see comments in scsi_host.h */
- host->max_id = 16;
- host->max_lun = 256;
- host->max_channel = pHba->top_scsi_channel + 1;
- host->cmd_per_lun = 1;
- host->unique_id = (uint) pHba;
- host->sg_tablesize = pHba->sg_tablesize;
- host->can_queue = pHba->post_fifo_size;
-
- if (scsi_add_host(host, &pHba->pDev->dev)) {
- scsi_host_put(host);
- return -1;
- }
-
- return 0;
-}
-
-static int __init adpt_init(void)
-{
- int count;
-
- printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
-#ifdef REBOOT_NOTIFIER
- register_reboot_notifier(&adpt_reboot_notifier);
-#endif
-
- count = adpt_detect();
-
- return count > 0 ? 0 : -ENODEV;
-}
-
-static void __exit adpt_exit(void)
-{
- while (hba_chain)
- adpt_release(hba_chain);
-}
-
-module_init(adpt_init);
-module_exit(adpt_exit);
+#include "scsi_module.c"
MODULE_LICENSE("GPL");