Loading drivers/scsi/hpsa.c +220 −1 Original line number Diff line number Diff line Loading @@ -159,6 +159,7 @@ static int hpsa_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason); static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd); static int hpsa_eh_abort_handler(struct scsi_cmnd *scsicmd); static int hpsa_slave_alloc(struct scsi_device *sdev); static void hpsa_slave_destroy(struct scsi_device *sdev); Loading @@ -180,6 +181,7 @@ static int __devinit hpsa_pci_find_memory_BAR(struct pci_dev *pdev, static int __devinit hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id); static int __devinit hpsa_wait_for_board_state(struct pci_dev *pdev, void __iomem *vaddr, int wait_for_ready); static inline void finish_cmd(struct CommandList *c); #define BOARD_NOT_READY 0 #define BOARD_READY 1 Loading Loading @@ -507,6 +509,7 @@ static struct scsi_host_template hpsa_driver_template = { .change_queue_depth = hpsa_change_queue_depth, .this_id = -1, .use_clustering = ENABLE_CLUSTERING, .eh_abort_handler = hpsa_eh_abort_handler, .eh_device_reset_handler = hpsa_eh_device_reset_handler, .ioctl = hpsa_ioctl, .slave_alloc = hpsa_slave_alloc, Loading Loading @@ -2352,6 +2355,191 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd) return FAILED; } static int hpsa_send_abort(struct ctlr_info *h, unsigned char *scsi3addr, struct CommandList *abort) { int rc = IO_OK; struct CommandList *c; struct ErrorInfo *ei; c = cmd_special_alloc(h); if (c == NULL) { /* trouble... */ dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); return -ENOMEM; } fill_cmd(c, HPSA_ABORT_MSG, h, abort, 0, 0, scsi3addr, TYPE_MSG); hpsa_scsi_do_simple_cmd_core(h, c); dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: do_simple_cmd_core completed.\n", __func__, abort->Header.Tag.upper, abort->Header.Tag.lower); /* no unmap needed here because no data xfer. */ ei = c->err_info; switch (ei->CommandStatus) { case CMD_SUCCESS: break; case CMD_UNABORTABLE: /* Very common, don't make noise. */ rc = -1; break; default: dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: interpreting error.\n", __func__, abort->Header.Tag.upper, abort->Header.Tag.lower); hpsa_scsi_interpret_error(c); rc = -1; break; } cmd_special_free(h, c); dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: Finished.\n", __func__, abort->Header.Tag.upper, abort->Header.Tag.lower); return rc; } /* * hpsa_find_cmd_in_queue * * Used to determine whether a command (find) is still present * in queue_head. Optionally excludes the last element of queue_head. * * This is used to avoid unnecessary aborts. Commands in h->reqQ have * not yet been submitted, and so can be aborted by the driver without * sending an abort to the hardware. * * Returns pointer to command if found in queue, NULL otherwise. */ static struct CommandList *hpsa_find_cmd_in_queue(struct ctlr_info *h, struct scsi_cmnd *find, struct list_head *queue_head) { unsigned long flags; struct CommandList *c = NULL; /* ptr into cmpQ */ if (!find) return 0; spin_lock_irqsave(&h->lock, flags); list_for_each_entry(c, queue_head, list) { if (c->scsi_cmd == NULL) /* e.g.: passthru ioctl */ continue; if (c->scsi_cmd == find) { spin_unlock_irqrestore(&h->lock, flags); return c; } } spin_unlock_irqrestore(&h->lock, flags); return NULL; } /* Send an abort for the specified command. * If the device and controller support it, * send a task abort request. */ static int hpsa_eh_abort_handler(struct scsi_cmnd *sc) { int i, rc; struct ctlr_info *h; struct hpsa_scsi_dev_t *dev; struct CommandList *abort; /* pointer to command to be aborted */ struct CommandList *found; struct scsi_cmnd *as; /* ptr to scsi cmd inside aborted command. */ char msg[256]; /* For debug messaging. */ int ml = 0; /* Find the controller of the command to be aborted */ h = sdev_to_hba(sc->device); if (WARN(h == NULL, "ABORT REQUEST FAILED, Controller lookup failed.\n")) return FAILED; /* Check that controller supports some kind of task abort */ if (!(HPSATMF_PHYS_TASK_ABORT & h->TMFSupportFlags) && !(HPSATMF_LOG_TASK_ABORT & h->TMFSupportFlags)) return FAILED; memset(msg, 0, sizeof(msg)); ml += sprintf(msg+ml, "ABORT REQUEST on C%d:B%d:T%d:L%d ", h->scsi_host->host_no, sc->device->channel, sc->device->id, sc->device->lun); /* Find the device of the command to be aborted */ dev = sc->device->hostdata; if (!dev) { dev_err(&h->pdev->dev, "%s FAILED, Device lookup failed.\n", msg); return FAILED; } /* Get SCSI command to be aborted */ abort = (struct CommandList *) sc->host_scribble; if (abort == NULL) { dev_err(&h->pdev->dev, "%s FAILED, Command to abort is NULL.\n", msg); return FAILED; } ml += sprintf(msg+ml, "Tag:0x%08x:%08x ", abort->Header.Tag.upper, abort->Header.Tag.lower); as = (struct scsi_cmnd *) abort->scsi_cmd; if (as != NULL) ml += sprintf(msg+ml, "Command:0x%x SN:0x%lx ", as->cmnd[0], as->serial_number); dev_dbg(&h->pdev->dev, "%s\n", msg); dev_warn(&h->pdev->dev, "Abort request on C%d:B%d:T%d:L%d\n", h->scsi_host->host_no, dev->bus, dev->target, dev->lun); /* Search reqQ to See if command is queued but not submitted, * if so, complete the command with aborted status and remove * it from the reqQ. */ found = hpsa_find_cmd_in_queue(h, sc, &h->reqQ); if (found) { found->err_info->CommandStatus = CMD_ABORTED; finish_cmd(found); dev_info(&h->pdev->dev, "%s Request SUCCEEDED (driver queue).\n", msg); return SUCCESS; } /* not in reqQ, if also not in cmpQ, must have already completed */ found = hpsa_find_cmd_in_queue(h, sc, &h->cmpQ); if (!found) { dev_dbg(&h->pdev->dev, "%s Request FAILED (not known to driver).\n", msg); return SUCCESS; } /* * Command is in flight, or possibly already completed * by the firmware (but not to the scsi mid layer) but we can't * distinguish which. Send the abort down. */ rc = hpsa_send_abort(h, dev->scsi3addr, abort); if (rc != 0) { dev_dbg(&h->pdev->dev, "%s Request FAILED.\n", msg); dev_warn(&h->pdev->dev, "FAILED abort on device C%d:B%d:T%d:L%d\n", h->scsi_host->host_no, dev->bus, dev->target, dev->lun); return FAILED; } dev_info(&h->pdev->dev, "%s REQUEST SUCCEEDED.\n", msg); /* If the abort(s) above completed and actually aborted the * command, then the command to be aborted should already be * completed. If not, wait around a bit more to see if they * manage to complete normally. */ #define ABORT_COMPLETE_WAIT_SECS 30 for (i = 0; i < ABORT_COMPLETE_WAIT_SECS * 10; i++) { found = hpsa_find_cmd_in_queue(h, sc, &h->cmpQ); if (!found) return SUCCESS; msleep(100); } dev_warn(&h->pdev->dev, "%s FAILED. Aborted command has not completed after %d seconds.\n", msg, ABORT_COMPLETE_WAIT_SECS); return FAILED; } /* * For operations that cannot sleep, a command block is allocated at init, * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track Loading Loading @@ -2884,6 +3072,7 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, int cmd_type) { int pci_dir = XFER_NONE; struct CommandList *a; /* for commands to be aborted */ c->cmd_type = CMD_IOCTL_PEND; c->Header.ReplyQueue = 0; Loading Loading @@ -2968,7 +3157,34 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, c->Request.CDB[6] = 0x00; c->Request.CDB[7] = 0x00; break; case HPSA_ABORT_MSG: a = buff; /* point to command to be aborted */ dev_dbg(&h->pdev->dev, "Abort Tag:0x%08x:%08x using request Tag:0x%08x:%08x\n", a->Header.Tag.upper, a->Header.Tag.lower, c->Header.Tag.upper, c->Header.Tag.lower); c->Request.CDBLen = 16; c->Request.Type.Type = TYPE_MSG; c->Request.Type.Attribute = ATTR_SIMPLE; c->Request.Type.Direction = XFER_WRITE; c->Request.Timeout = 0; /* Don't time out */ c->Request.CDB[0] = HPSA_TASK_MANAGEMENT; c->Request.CDB[1] = HPSA_TMF_ABORT_TASK; c->Request.CDB[2] = 0x00; /* reserved */ c->Request.CDB[3] = 0x00; /* reserved */ /* Tag to abort goes in CDB[4]-CDB[11] */ c->Request.CDB[4] = a->Header.Tag.lower & 0xFF; c->Request.CDB[5] = (a->Header.Tag.lower >> 8) & 0xFF; c->Request.CDB[6] = (a->Header.Tag.lower >> 16) & 0xFF; c->Request.CDB[7] = (a->Header.Tag.lower >> 24) & 0xFF; c->Request.CDB[8] = a->Header.Tag.upper & 0xFF; c->Request.CDB[9] = (a->Header.Tag.upper >> 8) & 0xFF; c->Request.CDB[10] = (a->Header.Tag.upper >> 16) & 0xFF; c->Request.CDB[11] = (a->Header.Tag.upper >> 24) & 0xFF; c->Request.CDB[12] = 0x00; /* reserved */ c->Request.CDB[13] = 0x00; /* reserved */ c->Request.CDB[14] = 0x00; /* reserved */ c->Request.CDB[15] = 0x00; /* reserved */ break; default: dev_warn(&h->pdev->dev, "unknown message type %d\n", cmd); Loading Loading @@ -3848,6 +4064,9 @@ static void __devinit hpsa_find_board_params(struct ctlr_info *h) h->maxsgentries = 31; /* default to traditional values */ h->chainsize = 0; } /* Find out what task management functions are supported and cache */ h->TMFSupportFlags = readl(&(h->cfgtable->TMFSupportFlags)); } static inline bool hpsa_CISS_signature_present(struct ctlr_info *h) Loading drivers/scsi/hpsa.h +21 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,27 @@ struct ctlr_info { u64 last_heartbeat_timestamp; u32 lockup_detected; struct list_head lockup_list; u32 TMFSupportFlags; /* cache what task mgmt funcs are supported. */ #define HPSATMF_BITS_SUPPORTED (1 << 0) #define HPSATMF_PHYS_LUN_RESET (1 << 1) #define HPSATMF_PHYS_NEX_RESET (1 << 2) #define HPSATMF_PHYS_TASK_ABORT (1 << 3) #define HPSATMF_PHYS_TSET_ABORT (1 << 4) #define HPSATMF_PHYS_CLEAR_ACA (1 << 5) #define HPSATMF_PHYS_CLEAR_TSET (1 << 6) #define HPSATMF_PHYS_QRY_TASK (1 << 7) #define HPSATMF_PHYS_QRY_TSET (1 << 8) #define HPSATMF_PHYS_QRY_ASYNC (1 << 9) #define HPSATMF_MASK_SUPPORTED (1 << 16) #define HPSATMF_LOG_LUN_RESET (1 << 17) #define HPSATMF_LOG_NEX_RESET (1 << 18) #define HPSATMF_LOG_TASK_ABORT (1 << 19) #define HPSATMF_LOG_TSET_ABORT (1 << 20) #define HPSATMF_LOG_CLEAR_ACA (1 << 21) #define HPSATMF_LOG_CLEAR_TSET (1 << 22) #define HPSATMF_LOG_QRY_TASK (1 << 23) #define HPSATMF_LOG_QRY_TSET (1 << 24) #define HPSATMF_LOG_QRY_ASYNC (1 << 25) }; #define HPSA_ABORT_MSG 0 #define HPSA_DEVICE_RESET_MSG 1 Loading drivers/scsi/hpsa_cmd.h +30 −1 Original line number Diff line number Diff line Loading @@ -82,6 +82,29 @@ #define TYPE_CMD 0x00 #define TYPE_MSG 0x01 /* Message Types */ #define HPSA_TASK_MANAGEMENT 0x00 #define HPSA_RESET 0x01 #define HPSA_SCAN 0x02 #define HPSA_NOOP 0x03 #define HPSA_CTLR_RESET_TYPE 0x00 #define HPSA_BUS_RESET_TYPE 0x01 #define HPSA_TARGET_RESET_TYPE 0x03 #define HPSA_LUN_RESET_TYPE 0x04 #define HPSA_NEXUS_RESET_TYPE 0x05 /* Task Management Functions */ #define HPSA_TMF_ABORT_TASK 0x00 #define HPSA_TMF_ABORT_TASK_SET 0x01 #define HPSA_TMF_CLEAR_ACA 0x02 #define HPSA_TMF_CLEAR_TASK_SET 0x03 #define HPSA_TMF_QUERY_TASK 0x04 #define HPSA_TMF_QUERY_TASK_SET 0x05 #define HPSA_TMF_QUERY_ASYNCEVENT 0x06 /* config space register offsets */ #define CFG_VENDORID 0x00 #define CFG_DEVICEID 0x02 Loading Loading @@ -337,11 +360,17 @@ struct CfgTable { u32 MaxPhysicalDevices; u32 MaxPhysicalDrivesPerLogicalUnit; u32 MaxPerformantModeCommands; u8 reserved[0x78 - 0x58]; u32 MaxBlockFetch; u32 PowerConservationSupport; u32 PowerConservationEnable; u32 TMFSupportFlags; u8 TMFTagMask[8]; u8 reserved[0x78 - 0x70]; u32 misc_fw_support; /* offset 0x78 */ #define MISC_FW_DOORBELL_RESET (0x02) #define MISC_FW_DOORBELL_RESET2 (0x010) u8 driver_version[32]; }; #define NUM_BLOCKFETCH_ENTRIES 8 Loading Loading
drivers/scsi/hpsa.c +220 −1 Original line number Diff line number Diff line Loading @@ -159,6 +159,7 @@ static int hpsa_change_queue_depth(struct scsi_device *sdev, int qdepth, int reason); static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd); static int hpsa_eh_abort_handler(struct scsi_cmnd *scsicmd); static int hpsa_slave_alloc(struct scsi_device *sdev); static void hpsa_slave_destroy(struct scsi_device *sdev); Loading @@ -180,6 +181,7 @@ static int __devinit hpsa_pci_find_memory_BAR(struct pci_dev *pdev, static int __devinit hpsa_lookup_board_id(struct pci_dev *pdev, u32 *board_id); static int __devinit hpsa_wait_for_board_state(struct pci_dev *pdev, void __iomem *vaddr, int wait_for_ready); static inline void finish_cmd(struct CommandList *c); #define BOARD_NOT_READY 0 #define BOARD_READY 1 Loading Loading @@ -507,6 +509,7 @@ static struct scsi_host_template hpsa_driver_template = { .change_queue_depth = hpsa_change_queue_depth, .this_id = -1, .use_clustering = ENABLE_CLUSTERING, .eh_abort_handler = hpsa_eh_abort_handler, .eh_device_reset_handler = hpsa_eh_device_reset_handler, .ioctl = hpsa_ioctl, .slave_alloc = hpsa_slave_alloc, Loading Loading @@ -2352,6 +2355,191 @@ static int hpsa_eh_device_reset_handler(struct scsi_cmnd *scsicmd) return FAILED; } static int hpsa_send_abort(struct ctlr_info *h, unsigned char *scsi3addr, struct CommandList *abort) { int rc = IO_OK; struct CommandList *c; struct ErrorInfo *ei; c = cmd_special_alloc(h); if (c == NULL) { /* trouble... */ dev_warn(&h->pdev->dev, "cmd_special_alloc returned NULL!\n"); return -ENOMEM; } fill_cmd(c, HPSA_ABORT_MSG, h, abort, 0, 0, scsi3addr, TYPE_MSG); hpsa_scsi_do_simple_cmd_core(h, c); dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: do_simple_cmd_core completed.\n", __func__, abort->Header.Tag.upper, abort->Header.Tag.lower); /* no unmap needed here because no data xfer. */ ei = c->err_info; switch (ei->CommandStatus) { case CMD_SUCCESS: break; case CMD_UNABORTABLE: /* Very common, don't make noise. */ rc = -1; break; default: dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: interpreting error.\n", __func__, abort->Header.Tag.upper, abort->Header.Tag.lower); hpsa_scsi_interpret_error(c); rc = -1; break; } cmd_special_free(h, c); dev_dbg(&h->pdev->dev, "%s: Tag:0x%08x:%08x: Finished.\n", __func__, abort->Header.Tag.upper, abort->Header.Tag.lower); return rc; } /* * hpsa_find_cmd_in_queue * * Used to determine whether a command (find) is still present * in queue_head. Optionally excludes the last element of queue_head. * * This is used to avoid unnecessary aborts. Commands in h->reqQ have * not yet been submitted, and so can be aborted by the driver without * sending an abort to the hardware. * * Returns pointer to command if found in queue, NULL otherwise. */ static struct CommandList *hpsa_find_cmd_in_queue(struct ctlr_info *h, struct scsi_cmnd *find, struct list_head *queue_head) { unsigned long flags; struct CommandList *c = NULL; /* ptr into cmpQ */ if (!find) return 0; spin_lock_irqsave(&h->lock, flags); list_for_each_entry(c, queue_head, list) { if (c->scsi_cmd == NULL) /* e.g.: passthru ioctl */ continue; if (c->scsi_cmd == find) { spin_unlock_irqrestore(&h->lock, flags); return c; } } spin_unlock_irqrestore(&h->lock, flags); return NULL; } /* Send an abort for the specified command. * If the device and controller support it, * send a task abort request. */ static int hpsa_eh_abort_handler(struct scsi_cmnd *sc) { int i, rc; struct ctlr_info *h; struct hpsa_scsi_dev_t *dev; struct CommandList *abort; /* pointer to command to be aborted */ struct CommandList *found; struct scsi_cmnd *as; /* ptr to scsi cmd inside aborted command. */ char msg[256]; /* For debug messaging. */ int ml = 0; /* Find the controller of the command to be aborted */ h = sdev_to_hba(sc->device); if (WARN(h == NULL, "ABORT REQUEST FAILED, Controller lookup failed.\n")) return FAILED; /* Check that controller supports some kind of task abort */ if (!(HPSATMF_PHYS_TASK_ABORT & h->TMFSupportFlags) && !(HPSATMF_LOG_TASK_ABORT & h->TMFSupportFlags)) return FAILED; memset(msg, 0, sizeof(msg)); ml += sprintf(msg+ml, "ABORT REQUEST on C%d:B%d:T%d:L%d ", h->scsi_host->host_no, sc->device->channel, sc->device->id, sc->device->lun); /* Find the device of the command to be aborted */ dev = sc->device->hostdata; if (!dev) { dev_err(&h->pdev->dev, "%s FAILED, Device lookup failed.\n", msg); return FAILED; } /* Get SCSI command to be aborted */ abort = (struct CommandList *) sc->host_scribble; if (abort == NULL) { dev_err(&h->pdev->dev, "%s FAILED, Command to abort is NULL.\n", msg); return FAILED; } ml += sprintf(msg+ml, "Tag:0x%08x:%08x ", abort->Header.Tag.upper, abort->Header.Tag.lower); as = (struct scsi_cmnd *) abort->scsi_cmd; if (as != NULL) ml += sprintf(msg+ml, "Command:0x%x SN:0x%lx ", as->cmnd[0], as->serial_number); dev_dbg(&h->pdev->dev, "%s\n", msg); dev_warn(&h->pdev->dev, "Abort request on C%d:B%d:T%d:L%d\n", h->scsi_host->host_no, dev->bus, dev->target, dev->lun); /* Search reqQ to See if command is queued but not submitted, * if so, complete the command with aborted status and remove * it from the reqQ. */ found = hpsa_find_cmd_in_queue(h, sc, &h->reqQ); if (found) { found->err_info->CommandStatus = CMD_ABORTED; finish_cmd(found); dev_info(&h->pdev->dev, "%s Request SUCCEEDED (driver queue).\n", msg); return SUCCESS; } /* not in reqQ, if also not in cmpQ, must have already completed */ found = hpsa_find_cmd_in_queue(h, sc, &h->cmpQ); if (!found) { dev_dbg(&h->pdev->dev, "%s Request FAILED (not known to driver).\n", msg); return SUCCESS; } /* * Command is in flight, or possibly already completed * by the firmware (but not to the scsi mid layer) but we can't * distinguish which. Send the abort down. */ rc = hpsa_send_abort(h, dev->scsi3addr, abort); if (rc != 0) { dev_dbg(&h->pdev->dev, "%s Request FAILED.\n", msg); dev_warn(&h->pdev->dev, "FAILED abort on device C%d:B%d:T%d:L%d\n", h->scsi_host->host_no, dev->bus, dev->target, dev->lun); return FAILED; } dev_info(&h->pdev->dev, "%s REQUEST SUCCEEDED.\n", msg); /* If the abort(s) above completed and actually aborted the * command, then the command to be aborted should already be * completed. If not, wait around a bit more to see if they * manage to complete normally. */ #define ABORT_COMPLETE_WAIT_SECS 30 for (i = 0; i < ABORT_COMPLETE_WAIT_SECS * 10; i++) { found = hpsa_find_cmd_in_queue(h, sc, &h->cmpQ); if (!found) return SUCCESS; msleep(100); } dev_warn(&h->pdev->dev, "%s FAILED. Aborted command has not completed after %d seconds.\n", msg, ABORT_COMPLETE_WAIT_SECS); return FAILED; } /* * For operations that cannot sleep, a command block is allocated at init, * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track Loading Loading @@ -2884,6 +3072,7 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, int cmd_type) { int pci_dir = XFER_NONE; struct CommandList *a; /* for commands to be aborted */ c->cmd_type = CMD_IOCTL_PEND; c->Header.ReplyQueue = 0; Loading Loading @@ -2968,7 +3157,34 @@ static void fill_cmd(struct CommandList *c, u8 cmd, struct ctlr_info *h, c->Request.CDB[6] = 0x00; c->Request.CDB[7] = 0x00; break; case HPSA_ABORT_MSG: a = buff; /* point to command to be aborted */ dev_dbg(&h->pdev->dev, "Abort Tag:0x%08x:%08x using request Tag:0x%08x:%08x\n", a->Header.Tag.upper, a->Header.Tag.lower, c->Header.Tag.upper, c->Header.Tag.lower); c->Request.CDBLen = 16; c->Request.Type.Type = TYPE_MSG; c->Request.Type.Attribute = ATTR_SIMPLE; c->Request.Type.Direction = XFER_WRITE; c->Request.Timeout = 0; /* Don't time out */ c->Request.CDB[0] = HPSA_TASK_MANAGEMENT; c->Request.CDB[1] = HPSA_TMF_ABORT_TASK; c->Request.CDB[2] = 0x00; /* reserved */ c->Request.CDB[3] = 0x00; /* reserved */ /* Tag to abort goes in CDB[4]-CDB[11] */ c->Request.CDB[4] = a->Header.Tag.lower & 0xFF; c->Request.CDB[5] = (a->Header.Tag.lower >> 8) & 0xFF; c->Request.CDB[6] = (a->Header.Tag.lower >> 16) & 0xFF; c->Request.CDB[7] = (a->Header.Tag.lower >> 24) & 0xFF; c->Request.CDB[8] = a->Header.Tag.upper & 0xFF; c->Request.CDB[9] = (a->Header.Tag.upper >> 8) & 0xFF; c->Request.CDB[10] = (a->Header.Tag.upper >> 16) & 0xFF; c->Request.CDB[11] = (a->Header.Tag.upper >> 24) & 0xFF; c->Request.CDB[12] = 0x00; /* reserved */ c->Request.CDB[13] = 0x00; /* reserved */ c->Request.CDB[14] = 0x00; /* reserved */ c->Request.CDB[15] = 0x00; /* reserved */ break; default: dev_warn(&h->pdev->dev, "unknown message type %d\n", cmd); Loading Loading @@ -3848,6 +4064,9 @@ static void __devinit hpsa_find_board_params(struct ctlr_info *h) h->maxsgentries = 31; /* default to traditional values */ h->chainsize = 0; } /* Find out what task management functions are supported and cache */ h->TMFSupportFlags = readl(&(h->cfgtable->TMFSupportFlags)); } static inline bool hpsa_CISS_signature_present(struct ctlr_info *h) Loading
drivers/scsi/hpsa.h +21 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,27 @@ struct ctlr_info { u64 last_heartbeat_timestamp; u32 lockup_detected; struct list_head lockup_list; u32 TMFSupportFlags; /* cache what task mgmt funcs are supported. */ #define HPSATMF_BITS_SUPPORTED (1 << 0) #define HPSATMF_PHYS_LUN_RESET (1 << 1) #define HPSATMF_PHYS_NEX_RESET (1 << 2) #define HPSATMF_PHYS_TASK_ABORT (1 << 3) #define HPSATMF_PHYS_TSET_ABORT (1 << 4) #define HPSATMF_PHYS_CLEAR_ACA (1 << 5) #define HPSATMF_PHYS_CLEAR_TSET (1 << 6) #define HPSATMF_PHYS_QRY_TASK (1 << 7) #define HPSATMF_PHYS_QRY_TSET (1 << 8) #define HPSATMF_PHYS_QRY_ASYNC (1 << 9) #define HPSATMF_MASK_SUPPORTED (1 << 16) #define HPSATMF_LOG_LUN_RESET (1 << 17) #define HPSATMF_LOG_NEX_RESET (1 << 18) #define HPSATMF_LOG_TASK_ABORT (1 << 19) #define HPSATMF_LOG_TSET_ABORT (1 << 20) #define HPSATMF_LOG_CLEAR_ACA (1 << 21) #define HPSATMF_LOG_CLEAR_TSET (1 << 22) #define HPSATMF_LOG_QRY_TASK (1 << 23) #define HPSATMF_LOG_QRY_TSET (1 << 24) #define HPSATMF_LOG_QRY_ASYNC (1 << 25) }; #define HPSA_ABORT_MSG 0 #define HPSA_DEVICE_RESET_MSG 1 Loading
drivers/scsi/hpsa_cmd.h +30 −1 Original line number Diff line number Diff line Loading @@ -82,6 +82,29 @@ #define TYPE_CMD 0x00 #define TYPE_MSG 0x01 /* Message Types */ #define HPSA_TASK_MANAGEMENT 0x00 #define HPSA_RESET 0x01 #define HPSA_SCAN 0x02 #define HPSA_NOOP 0x03 #define HPSA_CTLR_RESET_TYPE 0x00 #define HPSA_BUS_RESET_TYPE 0x01 #define HPSA_TARGET_RESET_TYPE 0x03 #define HPSA_LUN_RESET_TYPE 0x04 #define HPSA_NEXUS_RESET_TYPE 0x05 /* Task Management Functions */ #define HPSA_TMF_ABORT_TASK 0x00 #define HPSA_TMF_ABORT_TASK_SET 0x01 #define HPSA_TMF_CLEAR_ACA 0x02 #define HPSA_TMF_CLEAR_TASK_SET 0x03 #define HPSA_TMF_QUERY_TASK 0x04 #define HPSA_TMF_QUERY_TASK_SET 0x05 #define HPSA_TMF_QUERY_ASYNCEVENT 0x06 /* config space register offsets */ #define CFG_VENDORID 0x00 #define CFG_DEVICEID 0x02 Loading Loading @@ -337,11 +360,17 @@ struct CfgTable { u32 MaxPhysicalDevices; u32 MaxPhysicalDrivesPerLogicalUnit; u32 MaxPerformantModeCommands; u8 reserved[0x78 - 0x58]; u32 MaxBlockFetch; u32 PowerConservationSupport; u32 PowerConservationEnable; u32 TMFSupportFlags; u8 TMFTagMask[8]; u8 reserved[0x78 - 0x70]; u32 misc_fw_support; /* offset 0x78 */ #define MISC_FW_DOORBELL_RESET (0x02) #define MISC_FW_DOORBELL_RESET2 (0x010) u8 driver_version[32]; }; #define NUM_BLOCKFETCH_ENTRIES 8 Loading